Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Unity type registration for generic factory method

I'm trying to get familiar with asp.net mvc and currently I'm working on setting up logging.

I've had a look at Microsoft.Extensions.Logging and read about how to set it up but I'm struggling with the type registration in unity.

I'd like to setup the type for

public HomeController(ILogger<HomeController> logger)

I can do so with

    private static void RegisterLoggingTypes(IUnityContainer container)
    {
        ILoggerFactory loggerFactory = new LoggerFactory()
            .AddConsole()
            .AddDebug();
        container.RegisterType<ILogger<HomeController>>(new InjectionFactory(c => loggerFactory.CreateLogger<HomeController>()));
    }

But I don't want to have to declare one for every type. I tried

container.RegisterType(typeof(ILogger<>), new InjectionFactory((c,t,s) => loggerFactory.CreateLogger(t)));

But this is returning an ILogger instead of an ILogger(of HomeController)

Any idea how I can do this?

Thanks

like image 772
FloatingKiwi Avatar asked Oct 02 '16 23:10

FloatingKiwi


1 Answers

I've figured this out. I needed to use reflection to generate the generic method then to invoke that.

        var factoryMethod = typeof(LoggerFactoryExtensions).
                            GetMethods(System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.Public).
                            First(x => x.ContainsGenericParameters);

        container.RegisterType(typeof(ILogger<>), new InjectionFactory((c, t, s) =>
        {
            var genFactoryMethod = factoryMethod.MakeGenericMethod(t.GetGenericArguments()[0]);
            return genFactoryMethod.Invoke(null, new object[] { loggerFactory });
        }));
like image 106
FloatingKiwi Avatar answered Nov 08 '22 02:11

FloatingKiwi