Search code examples
.netsimple-injector

Set Simple Injector's Logger


I've set my application to use Simple Injector as DI container, I've registered all the repositories/services and I was looking to set up the latest step: Logging what Simple Injector writes as output during its own business.

Now I'm not talking how to register a Logger (in my specific case I use log4net, but this applies to all the logging framework, but how do I tell Simple Injector to log using log4net? I've not seen any .Log as for example Unity does


Solution

  • Simple Injector, internally, does not log anything at all. This is a very explicit design decision, because instead of reporting warnings and errors through a logging system that nobody will ever look at, Simple Injector's API is designed specifically to prevent errors, and it throws exceptions when it detects problems, such as ambiguity.

    Exceptions that communicate problems are thrown at several stages. First of all, during registration all kinds of conditions and constraints are checked. Second, when calling .Verify(), Simple Injector checks whether it can build all registered types and does all kind of analysis to verify whether your object graphs are structured sanely. As a last resort, in case Verify was not called, some checks are performed when a service is resolved for the first time.

    Simple Injector does, however, provide two APIs to get textual information about its registrations.

    Instead of calling Verify(), you can use the Analyzer to get structured information about validation results. This will include diagnostic info (i.e. tips) about your graph that won't cause Verify to throw. The following test, for instance, can be added to your test suite:

    [TestMethod]
    public void Container_Never_ContainsDiagnosticWarnings() {
        // Arrange
        var container = Bootstrapper.GetInitializedContainer();
    
        container.Verify(VerificationOption.VerifyOnly);
    
        // Assert
        var results = Analyzer.Analyze(container);
    
        Assert.IsFalse(results.Any(), Environment.NewLine +
            string.Join(Environment.NewLine,
                from result in results
                select result.Description));
    }
    

    For more information about this, see the documentation about Diagnostics.

    Simple Injector also allows visualizing object graphs by building a C#-like string representation of the object graph. This can be done by calling InstanceProducer.VisualizeObjectGraph(). An InstanceProducer can be obtained by calling Container.GetRegistration() or Container.GetRegistration(Type). Here's an example:

    var container = new Container();
    
    container.Register<Foo>();
    container.Register<IBar, Bar>();
    container.Register<ILogger, FileLogger>(Lifestyle.Singleton);
    container.Register<IDependency1, Dependency1>();
    container.Register<IDependency2, Dependency2>();
    
    // You need to verify to get the correct output of those methods
    container.Verify();
    
    var r = container.GetRegistration(typeof(Foo));
    
    Console.WriteLine(r.VisualizeObjectGraph());
    

    This might result in the following output:

    Foo(
        FileLogger(
            Dependency1(),
            Dependency2()),
        Bar(
            Dependency1(),
            SomeService()));