mko
mko

Reputation: 7335

Alternative for injecting a IUnityContainer dependency when using Microsoft.Extensions.DependencyInjection in ASP.NET Core?

So in asp.net 4 I had this class

 public class Dispatcher : IDispatcher
    {
        private IUnityContainer container;

        public Dispatcher(IUnityContainer container)
        {
            this.container = container;
        }

        public async Task Dispatch<T>(T evt) where T : IAtomicEvent
        {
            try
            {
                var d1 = typeof(IHandlesAtomically<>);
                Type[] typeArgs = { evt.GetType() };
                var makeme = d1.MakeGenericType(typeArgs);

                var handler = container.Resolve(makeme);
                await ((Task)handler.GetType()
                      .GetMethod("HandleAsync")
                      .Invoke(handler, new object[] { evt }));
            }
            catch (Exception ex)
            {
                throw;
            }


            return;
        }

and in UnityConfig I had

container.RegisterType<IDispatcher, Dispatcher>();
container.RegisterType<IHandlesAtomically<PromotionCreated>, PromotionCreatedHandler>();

In asp.net core Startup.cs I have added

services.AddSingleton<IDispatcher, Dispatcher>();
services.AddSingleton<IHandlesAtomically<PromotionCreated>, PromotionCreatedHandler>();

The error I am getting is

InvalidOperationException: Unable to resolve service for type 'Unity.IUnityContainer' while attempting to activate 'RatesAvailability.Infrastructure.Dispatcher.Dispatcher'.

So how can I resolve makeme without using IUnityContainer?

Upvotes: 1

Views: 1302

Answers (1)

Nkosi
Nkosi

Reputation: 247551

Replace the container with IServiceProvider and use that to resolve services

public class Dispatcher : IDispatcher {
    private readonly IServiceProvider provider;

    public Dispatcher(IServiceProvider provider) {
        this.provider = provider
    }

    public Task Dispatch<T>(T evt) where T : IAtomicEvent {
        try {
            var d1 = typeof(IHandlesAtomically<>);
            Type[] typeArgs = { evt.GetType() };
            var makeme = d1.MakeGenericType(typeArgs);

            var handler = provider.GetService(makeme);
            return ((Task)handler.GetType()
                  .GetMethod("HandleAsync")
                  .Invoke(handler, new object[] { evt }));
        } catch (Exception ex) {
            throw;
        }
    }
}

If there are issues injecting the provider by default then consider using the factory delegate when configuring services

services.AddSingleton<IDispatcher>(serviceProvider => new Dispatcher(serviceProvider));

Upvotes: 2

Related Questions