I have a custom HTTP Module. I would like to inject the logger using my IoC framework, so I can log errors in the module. However, of course I don't get a constructor, so can't inject it into that. What's the best way to go about this?
If you need the specific IoC container - I'm currently using Windsor, but may soon move to AutoFac.
Thanks
Dependency injection (also known as DI) is a design pattern in which a class or object has its dependent classes injected (passed to it by another class or object) rather than create them directly. Dependency injection facilitates loose coupling and promotes testability and maintenance.
ASP.NET Core supports the dependency injection (DI) software design pattern, which is a technique for achieving Inversion of Control (IoC) between classes and their dependencies.
ASP.NET Core injects objects of dependency classes through constructor or method by using built-in IoC container. The built-in container is represented by IServiceProvider implementation that supports constructor injection by default.
First time I saw dependency injection to HttpModules in Spring.NET (not advertising this framework though). The idea is that you have special HttpModule which injects dependencies to other application-level HttpModule-s.
Unfortunatelly current version of Autofac.Integration.Web does not support this, but you can easily do that yourself:
public class MyModule : IHttpModule
{
public void Dispose()
{
}
public void Init(HttpApplication context)
{
Assert.IsNotNull(MyService);
}
public IMyService MyService { get; set; }
}
public class HttpModuleInjectionModule : IHttpModule
{
public void Dispose()
{
}
public void Init(HttpApplication context)
{
var containerProviderAccessor = context as IContainerProviderAccessor;
if(containerProviderAccessor == null)
throw new InvalidOperationException("HttpApplication should implement IContainerProviderAccessor");
var rootContainer = containerProviderAccessor.ContainerProvider.ApplicationContainer;
foreach (string moduleName in context.Modules.AllKeys)
rootContainer.InjectProperties(context.Modules[moduleName]);
}
}
public class Global : HttpApplication, IContainerProviderAccessor
{
static IContainerProvider _containerProvider;
protected void Application_Start(object sender, EventArgs e)
{
var builder = new ContainerBuilder();
builder.Register<MyService>().As<IMyService>();
_containerProvider = new ContainerProvider(builder.Build());
}
public IContainerProvider ContainerProvider
{
get { return _containerProvider; }
}
}
HttpModuleInjectionModule should be registered before other HttpModule-s in web.config:
<httpModules>
<add name="ScriptModule" type="System.Web.Handlers.ScriptModule, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
<add name="HttpModuleInjection" type="WebTest.HttpModuleInjectionModule, WebTest"/>
<add name="ContainerDisposal" type="Autofac.Integration.Web.ContainerDisposalModule, Autofac.Integration.Web"/>
<add name="PropertyInjection" type="Autofac.Integration.Web.PropertyInjectionModule, Autofac.Integration.Web"/>
<add name="MyModule" type="WebTest.MyModule, WebTest"/>
</httpModules>
I'm sure you can do similar things in Windsor. The difference would be in how you access your root container from HttpModuleInjectionModule.
I just answered this question on my blog.
See also http://lozanotek.com/blog/archive/2009/08/19/Autowire_IHttpModules_with_IoC.aspx
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With