Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cannot use more than one gateway transformation #250

Open
alex91352 opened this issue Aug 22, 2023 · 2 comments
Open

Cannot use more than one gateway transformation #250

alex91352 opened this issue Aug 22, 2023 · 2 comments

Comments

@alex91352
Copy link

The method GatewayRegistrations.AddGateway<TSubscription, TSubscriptionOptions, TProducer, TProduceOptions, TTransform> registers a GatewayHandler in the SubscriptionBuilder.

Since AddGateway passes the GatewayHandler to AddEventHandler as an IEventHandler, and AddEventHandler tries to register the handler in the service collection as a singleton, this means that only the first GatewayHandler is registered in the service collection. As a result, the first GatewayHandler (and its transformation) is used for all gateway subscriptions.

public static IServiceCollection AddGateway<TSubscription, TSubscriptionOptions, TProducer, TProduceOptions, TTransform>(
this IServiceCollection services,
string subscriptionId,
Action<TSubscriptionOptions>? configureSubscription = null,
Action<SubscriptionBuilder<TSubscription, TSubscriptionOptions>>? configureBuilder = null,
bool awaitProduce = true
)
where TSubscription : EventSubscription<TSubscriptionOptions>
where TProducer : class, IEventProducer<TProduceOptions>
where TProduceOptions : class
where TTransform : class, IGatewayTransform<TProduceOptions>
where TSubscriptionOptions : SubscriptionOptions {
services.TryAddSingleton<TTransform>();
services.AddSubscription<TSubscription, TSubscriptionOptions>(
subscriptionId,
builder => {
builder.Configure(configureSubscription);
configureBuilder?.Invoke(builder);
builder.AddEventHandler(GetHandler);
}
);
return services;
IEventHandler GetHandler(IServiceProvider sp) {
var transform = sp.GetRequiredService<TTransform>();
var producer = sp.GetRequiredService<TProducer>();
return new GatewayHandler<TProduceOptions>(new GatewayProducer<TProduceOptions>(producer), transform.RouteAndTransform, awaitProduce);
}
}

public SubscriptionBuilder AddEventHandler<THandler>(Func<IServiceProvider, THandler> getHandler)
where THandler : class, IEventHandler {
Services.TryAddSingleton(getHandler);
AddHandlerResolve(sp => sp.GetRequiredService<THandler>());
return this;
}

For example, if I register two gateway subscriptions:

services.AddGateway<StreamSubscription, StreamSubscriptionOptions, EventStoreProducer, EventStoreProduceOptions, SellOrderTransformation>("SellOrders", ...);
services.AddGateway<StreamSubscription, StreamSubscriptionOptions, EventStoreProducer, EventStoreProduceOptions, BuyOrderTransformation>("BuyOrders", ...);

then both subscriptions will use SellOrderTransformation.

@alexeyzimarev
Copy link
Contributor

alexeyzimarev commented Aug 22, 2023

Yeah, that can actually be fixed the same way as event handlers and checkpoint stores are attached to subscriptions. The problem is that gateways DI integration is way less comprehensive than DI stuff for subs as it took me weeks to figure things out there. It definitely worth spending time and figure better DI support for gateways as well.

@gius
Copy link

gius commented May 6, 2024

Hi, any update on this? How do you use multiple gateways? Or do you use just a single gateway for all cases?

A quick workaround we use is to create a custom sub class of TProduceOptions per subscription.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants