.netdependency-injectionunity-container.net-4.8

Resolving Microsoft Logger with Unity throws error


I am using .NET 4.8. and I registered Microsoft.Logger with unity injection:

var factory = new LoggerFactory();
factory.AddLog4Net("log4net.config");
container.RegisterInstance<ILoggerFactory>(factory);
container.RegisterType(typeof(ILogger<>), typeof(Logger<>));

After that, I am resolving all registrations, but I am receiving an error: Resolving Microsoft.Extensions.Logging.ILogger`1[TCategoryName][],(none) ---> System.InvalidOperationException: Could not execute the method because either the method itself or the containing type is not fully instantiated.

foreach (var item in _unityContainer.Registrations)
            {
                var named = _unityContainer.ResolveAll(item.RegisteredType);
                if (_unityContainer.IsRegistered(item.RegisteredType))
                {
                    var tmp = _unityContainer.Resolve(item.RegisteredType);
                }
            }

Solution

  • You are trying to resolve an open-generic type. Open-generic types, like Logger<T> can't be resolved just as you can't new an open-generic Logger<T>. Instead you can create a closed-generic Logger<SomeType>, but not Logger<T>.

    You will have to filter out all open-generic registrations from your validation procedure. For instance:

    foreach (var item in _unityContainer.Registrations)
    {
        // Add this line
        if (item.RegisteredType.ContainsGenericTypeConstraints) continue;
    
        var named = _unityContainer.ResolveAll(item.RegisteredType);
        if (_unityContainer.IsRegistered(item.RegisteredType))
        {
            var tmp = _unityContainer.Resolve(item.RegisteredType);
        }
    }
    

    This will prevent open-generic types from being resolved as root type. Most open-generic types are injected as dependencies of a closed or non-generic type. This means that you can still validate all the application's object graphs.

    Only care has been taken once you have open-generic registrations that are resolved as root types. You can do one of the following to allow them to be validated:

    • Instead of registering those root types as open-generic, consider registering all required closed versions explicitly.
    • Explicitly resolve one or a few closed versions of those open-generic root types as part of your validation process.