11

カスタムHTTPモジュールがあります。IoCフレームワークを使用してロガーを挿入したいので、モジュールにエラーを記録できます。ただし、もちろんコンストラクターを取得していないので、コンストラクターを挿入することはできません。これについて行くための最良の方法は何ですか?

特定のIoCコンテナが必要な場合-私は現在Windsorを使用していますが、まもなくAutoFacに移行する可能性があります。

ありがとう

4

4 に答える 4

10

Spring.NET で HttpModules への依存性注入を初めて見ました (ただし、このフレームワークは宣伝していません)。アイデアは、依存関係を他のアプリケーションレベルの HttpModule-s に注入する特別な HttpModule があるということです。

残念ながら、現在のバージョンの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 は、web.config で他の HttpModule-s の前に登録する必要があります。

  <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からルート コンテナーにアクセスする方法にあります。

于 2009-11-09T08:42:56.817 に答える
5

ブログでこの質問に答えたところです。

http://lozanotek.com/blog/archive/2009/08/19/Autowire_IHttpModules_with_IoC.aspxも参照してください。

于 2009-11-01T19:59:18.670 に答える
3

Initメソッドによって渡されたHttpApplicationコンテキストを介して、必要な依存関係を渡すことができます...

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

    public void Dispose()
    {
    }
}
于 2009-11-03T08:25:54.687 に答える
1

アンドレイ・ツィクノフの答えに興味がありますが、コメントする担当者がいません。

私は 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; }
}
于 2010-09-10T16:28:33.617 に答える