IoC Dependency injection into Custom HTTP Module - how? (ASP.NET)

家住魔仙堡 提交于 2019-11-30 07:27:09

问题


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


回答1:


I just answered this question on my blog.

See also http://lozanotek.com/blog/archive/2009/08/19/Autowire_IHttpModules_with_IoC.aspx




回答2:


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.




回答3:


You could pass in the required dependencies via the HttpApplication context passed to you by the Init method...

public class MyHttpModule : IHttpModule
{
    public void Init(HttpApplication context)
    {
        var dependency = (IDependency)context.Context.Items["dependency"];
        // consume dependency...
    }

    public void Dispose()
    {
    }
}



回答4:


I am curious about andrey-tsykunov's answer, but don't have the rep to comment on it.

I am trying to get comfortable with IoC and DI, so I may be missing something, but wouldn't it be simpler to use IContainerProviderAccessor from within MyModule, rather than create another module?

For example:

public class MyModule : IHttpModule
{
    public void Dispose()
    {            
    }

    public void Init(HttpApplication context)
    {
        Assert.IsNotNull(MyService);

        var containerProviderAccessor = context as IContainerProviderAccessor;

        if (accessor != null)
        {
            IContainer container = containerProviderAccessor.ContainerProvider.ApplicationContainer;
            MyService = container.Resolve<IMyService>();
        }
    }

    private IMyService MyService { get; set; }
}


来源:https://stackoverflow.com/questions/1657473/ioc-dependency-injection-into-custom-http-module-how-asp-net

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!