11

我有一個自定義HTTP模塊。我想用我的IoC框架注入記錄器,這樣我就可以在模塊中記錄錯誤。然而,當然我沒有得到一個構造函數,所以不能將它注入到構造函數中。什麼是最好的方式去做這件事?IoC依賴注入到自定義HTTP模塊 - 如何? (ASP.NET)

如果您需要特定的IoC容器 - 我目前使用的是Windsor,但可能會很快轉移到AutoFac。

謝謝

+0

你可以使用一個服務定位器,看看這個問題:([依賴注入和服務定位器模式之間的不同] http://stackoverflow.com/questions/1557781/ what-the-the-difference-between-dependency-injection-and-service-locator-patter) – FinnNk 2009-11-01 16:00:21

回答

2

見你可以在需要的依賴通過由init方法傳遞給你的HttpApplication的情況下通過......

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

    public void Dispose() 
    { 
    } 
} 
+2

-1,因爲很難用這種方式嘲笑依賴關係 – 2009-11-03 15:48:42

+0

@Mauricio Scheffer:也許,但隨後只是將模塊實現爲卑微的可執行文件。我更喜歡使用靜態注入的方法。人們認爲它有助於可測性,但它確實傷害了它。 – 2009-11-03 16:22:12

+1

在這種情況下,Humble Executable當然可以很好地工作,我會將該信息添加到答案中。但是,你可以吃你的蛋糕,也可以吃它,看看我的解決方案。 – 2009-11-03 16:41:34

10

第一次見到依賴注入的HttpModules在春季。 NET(不是通過這個框架)。這個想法是你有特殊的HttpModule,它將依賴注入到其他應用程序級別的HttpModule-s。

可惜的是的Autofac.Integration.Web當前版本不支持這一點,但你可以很容易地做到這一點你自己:

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應先於其他的HttpModule-S在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> 

我相信你可以在溫莎做類似的事情。區別在於如何從HttpModuleInjectionModule訪問根容器。

+0

這是相當有限的,不能做構造函數注入。 – 2010-10-07 20:38:18

1

我很想知道andrey-tsykunov的回答,但沒有代表發表評論。

我想使用IoC和DI,所以我可能會丟失一些東西,但是從MyModule中使用IContainerProviderAccessor會更簡單,而不是創建另一個模塊?

例如:

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; } 
} 
+4

您在這裏沒有執行依賴注入,您正在執行服務位置。 – 2010-10-07 20:40:02

+3

看起來像你有rep事物排序:P – 2014-09-20 07:47:08