Search code examples
c#.netlog4netninject

Log ninject resolved dependencies application start-up


We have started using Ninject version 2 as our IoC container along with the extension for resolving by naming conventions. We are also using log4net for our logging.

What I would like is for Ninject to log all the dependencies it has found and what will resolve them to, preferably on the application start-up.

I have found the logging extension, but can't find documentation or examples on how to use it to get this.

Edit:

Since it was requested here is the class that logs the default bindings on startup, using log4net

public class DefaultBindingGeneratorWithLogging : IBindingGenerator { private readonly IKernel kernel;

    /// <summary>
    /// Initializes a new instance of the <see cref="DefaultBindingGeneratorWithLogging"/> class.
    /// </summary>
    /// <param name="kernel">The kernel.</param>
    public DefaultBindingGeneratorWithLogging(IKernel kernel)
    {
        this.kernel = kernel;
    }

    /// <summary>
    /// Creates the bindings for a type.
    /// </summary>
    /// <param name="type">The type for which the bindings are created.</param>
    /// <param name="bindingRoot">The binding root that is used to create the bindings.</param>
    /// <returns>
    /// The syntaxes for the created bindings to configure more options.
    /// </returns>
    public IEnumerable<IBindingWhenInNamedWithOrOnSyntax<object>> CreateBindings(Type type, IBindingRoot bindingRoot)
    {
        if (type.IsInterface || type.IsAbstract)
        {
            yield break;
        }

        Type interfaceForType = type.GetInterface("I" + type.Name, false);
        if (interfaceForType == null)
        {
            yield break;
        }

        var log = kernel.Get<ILog>();
        if (!(kernel.GetBindings(interfaceForType).Any()))
        {
            bindingRoot.Bind(interfaceForType).To(type).InTransientScope();
            if (log.IsInfoEnabled && !String.IsNullOrWhiteSpace(interfaceForType.FullName))
            {
                log.InfoFormat("Mapping {0} -> {1}", type.FullName, interfaceForType.FullName);
            }
        }
        else
        {                
            log.InfoFormat("Didn't map {0} -> {1} mapping already exists", type.FullName, interfaceForType.FullName);
        }
    }
}

Solution

  • You can probably achieve what you are trying to do by creating your own instance of 'ActivationStrategy'. Here is one that I was using to monitor activation / deactivation:

    public class MyMonitorActivationStrategy : ActivationStrategy
    {
        private ILogger _logger;
    
        public override void Activate(Ninject.Activation.IContext context, Ninject.Activation.InstanceReference reference)
        {
            if(reference.Instance is ILogger)
            {
                _logger = (ILogger)reference.Instance;
            }
            _logger.Debug("Ninject Activate: " + reference.Instance.GetType());
            base.Activate(context, reference);
        }
    
        public override void Deactivate(Ninject.Activation.IContext context, Ninject.Activation.InstanceReference reference)
        {
            _logger.Debug("Ninject DeActivate: " + reference.Instance.GetType());
            base.Deactivate(context, reference);
        }
    }
    

    You wire this when you create your kernel.

        protected override IKernel CreateKernel()
        {
        var kernel = new StandardKernel();
            kernel.Components.Add<IActivationStrategy, MyMonitorActivationStrategy>();
    
            kernel.Load<AppModule>();
    
            return kernel;
        }
    

    Hope this helps.

    Bob