IHttpModule in ASP.NET MVC with SimpleInject

Mar 16, 2013 at 3:52 PM
Edited Mar 16, 2013 at 3:55 PM
Hi,

How can I do the follow:
public class Language : System.Web.IHttpModule
{
    private readonly ILanguageRepository languageRepository;

    public Language() {   }

    public Language(ILanguageRepository languageRepository)
    {
        this.languageRepository = languageRepository;            
     }      
}
With:
public static class SimpleInjectorInitializer
{
    /// <summary>Initialize the container and register it as MVC3 Dependency Resolver.</summary>
    public static void Initialize()
    {
        (...)
    }
     
    private static void InitializeContainer(Container container)
    {
        container.RegisterPerWebRequest<DbContext>(() => new DbContext());
        container.RegisterPerWebRequest<ILanguageRepository, LanguageRepository>();
        container.RegisterPerWebRequest<IPageContentRepository, PageContentRepository>();
    }
}
There is anyway to do this? Should I use Simple Injector like ASP.NET Web Forms example in my MVC application to gain access containter through Global? Like this:
public Language()
{ 
    this.languageRepository = Global.GetInstance<ILanguageRepository>();
}
If so, I have to drop SimpleInjectorInitializer for ASP.NET MVC application?

Thank you for help!
Coordinator
Mar 16, 2013 at 8:00 PM
Edited Mar 20, 2013 at 11:38 AM
There is no way (or at least not that I know of) to intercept the creation of HTTP modules, as there is a way to intercept the creation of MVC Controllers (using a custom IDependencyResolver) and ASP.NET Web Page (using a PageHandlerFactory). This means that you can’t use constructor injection when the module is created by ASP.NET. So you basically have two options:

Option 1: Fall back to Service Location inside your module:
public class LanguageHttpModule : System.Web.IHttpModule
{
    private readonly ILanguageRepository languageRepository;

    public LanguageHttpModule() : this(
        DependencyResolver.Current.GetService<ILanguageRepository>())
    {
    }

    public LanguageHttpModule(ILanguageRepository languageRepository)
    {
        if (languageRepository == null) throw new ArgumentNullException();

        this.languageRepository = languageRepository;            
    }      
}
Here we let the default constructor call the MVC DependencyResolver.Current.GetService. This will call into the Simple Injector Container and will resolve the ILanguageRepository. DependencyResolver.GetService however might return null when it is not configured, so we have to do a null check to prevent any NullReferenceExceptions later on.

The trick here is when you take this approach to make your HTTP module as thin as possible and forward as much as you can to its dependencies. This allows as much code as possible to be testable.

Additionally, you can register this module in code, instead of configuration:
DynamicModuleUtility.RegisterModule(typeof(LanguageHttpModule));
Option 2: Register the module in code on Pre Application Start

This option has been removed. I'm sorry, but this made no sense :-(
Marked as answer by dot_NET_Junkie on 11/5/2013 at 7:37 AM
Mar 16, 2013 at 10:59 PM
Your 1st option works well! I'm not using EF, I'm using OpenAccess ORM.

Thank you very much! Your help had been precious! :)