Register IAuthenticationManager with Simple Injector

As TrailMax already mentioned, the exception you got probably got raised during the call to container.Verify(). At application start-up time there is no HttpContext, hence the exception.

Although the removal of the call to container.Verify() will ‘solve’ the problem, I would advise against doing this and I will suggest a better solution below.

NightOwl888 references an old article of Mark Seemann (which I highly respect for his work on DI). In that article Mark explains why he thinks that verifying the container is useless. This article however seems outdated, and conflicts with newer articles from Mark. In a newer article Mark explains that one of the big advantages of using Pure DI (that is Dependency Injection without using a DI container) is that it provides the fastest feedback about correctness that you can get. Mark, and the rest of us, obviously values both the compiler’s feedback and the feedback from static code analysis tools, as rapid feedback mechanism. Both Simple Injector’s .Verify() and the Diagnostic Services attempt to bring this fast feedback back. In my view, Simple Injector’s .Verify() method takes on the job that the compiler would do for you when doing Pure DI and the Diagnostic Services is in a sense static code analysis tool specialized to your DI configuration.

While it is indeed not possible for a container to do a 100% verification of its configuration, verifying still proved a valuable practice to me. It would be silly to think that a simple call to .Verify() would result in a completely bug free or even a working application. If somebody may think that this is what ‘verifying’ your DI configuration means, I understand why they would argue that this functionality is worthless. Sounds like a statement of truism. There is no container out there, including Simple Injector, which pretends having such a feature.

You are off course still responsible for writing integration and/or unit tests for e.g. detecting if the order of applied decorators is correct or if all implementations of ISomeService<T> are indeed registered in the container.

I want to mention 2 specific arguments from Mark’s blog against verifying the container.

It is easy to get into the situation that the container verifies, but still breaks at runtime.

I agree with that, but I do think that the Simple Injector documentation has got some great guidance on how to approach this here.

When doing convention over configuration it’s easy to get registrations that shouldn’t be in the container anyway.

I never had this problem, because I think it is a sane practice to prevent getting in this situation anyway.

Back to the question:

Although one of the tips in the Simple Injector documentation is to use abstract factories, I wouldn’t do that in this case. Creating a factory for something that already exists, sounds pretty weird to me. Maybe it is just a problem of correct naming, but why would an AccountController need a AuthenticationFactory or AuthenticationContext? In other words, why should the application know anything about us having problem wiring things up because of some design quirks in ASP.NET Identity?

Instead, by adjusting the registration for the IAuthenticationManager we can return an Authentication component from a newly created OwinContext at startup/verify time and return the ‘normal’ or configured AuthenticationManager at runtime. This will remove the need for a factory and moves the responsibility to the Composition Root where it should be. And lets you inject the IAuthenticationManager everywhere you need it, while still being able to make a call to .Verify().

The code looks like:

container.RegisterPerWebRequest<IAuthenticationManager>(() => 
    AdvancedExtensions.IsVerifying(container) 
        ? new OwinContext(new Dictionary<string, object>()).Authentication 
        : HttpContext.Current.GetOwinContext().Authentication); 

An even more SOLID solution however would be to not depend on the IAuthenticationManager at all, because depending on this interface causes us to violate the Interface Segregation Principle, making it hard to create a proxy implementation for it that delays the creation.

You could do this by defining an abstraction which fits your needs and only your needs. Looking at the identity template calls to the IAuthenticationManager this abstraction would need nothing more than the .SignIn() and .SignOut() methods. This however would force you to completely refactor the crappy AccountController that you got ‘for free’ by the Visual Studio template, which can be quite an undertaking.

Leave a Comment