So, the EasyNetQ auto subscriber has a basic default dispatcher that cannot create message consumer classes with non-parameterless constructors.
To see that in action, create a consumer with a required dependency. You can setup your own service or you can use ILogger<T>
, which is registered automatically by the framework defaults.
ConsumeTextMessage.cs
public class ConsumeTextMessage : IConsume<TextMessage>
{
private readonly ILogger<ConsumeTextMessage> logger;
public ConsumeTextMessage(ILogger<ConsumeTextMessage> logger)
{
this.logger = logger;
}
public void Consume(TextMessage message)
{
...
}
}
Wire up the auto subscriber (there's some leeway here as far as where/when to write/run this code).
Startup.cs
public void ConfigureServices(IServiceCollection services)
{
services.AddSingleton<IBus>(RabbitHutch.CreateBus("host=localhost"));
}
(Somewhere else, maybe startup.Configure
or a BackgroundService
)
var subscriber = new AutoSubscriber(bus, "example");
subscriber.Subscribe(Assembly.GetExecutingAssembly());
Now, start the program and publish some messages, you should see every message end up in the default error queue.
System.MissingMethodException: No parameterless constructor defined for this object.
at System.RuntimeTypeHandle.CreateInstance(RuntimeType type, Boolean publicOnly, Boolean wrapExceptions, Boolean& canBeCached, RuntimeMethodHandleInternal& ctor)
at System.RuntimeType.CreateInstanceSlow(Boolean publicOnly, Boolean wrapExceptions, Boolean skipCheckThis, Boolean fillCache)
at System.Activator.CreateInstance[T]()
at EasyNetQ.AutoSubscribe.DefaultAutoSubscriberMessageDispatcher.DispatchAsync[TMessage,TAsyncConsumer](TMessage message)
at EasyNetQ.Consumer.HandlerRunner.InvokeUserMessageHandlerInternalAsync(ConsumerExecutionContext context)
I know that I can provide my own dispatcher, but how do we get that working with the ASP.NET Core services provider; ensuring that this works with scoped services?