カスタムHTTPモジュールがあります。IoCフレームワークを使用してロガーを挿入したいので、モジュールにエラーを記録できます。ただし、もちろんコンストラクターを取得していないので、コンストラクターを挿入することはできません。これについて行くための最良の方法は何ですか?
特定のIoCコンテナが必要な場合-私は現在Windsorを使用していますが、まもなくAutoFacに移行する可能性があります。
ありがとう
カスタムHTTPモジュールがあります。IoCフレームワークを使用してロガーを挿入したいので、モジュールにエラーを記録できます。ただし、もちろんコンストラクターを取得していないので、コンストラクターを挿入することはできません。これについて行くための最良の方法は何ですか?
特定のIoCコンテナが必要な場合-私は現在Windsorを使用していますが、まもなくAutoFacに移行する可能性があります。
ありがとう
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からルート コンテナーにアクセスする方法にあります。
Initメソッドによって渡されたHttpApplicationコンテキストを介して、必要な依存関係を渡すことができます...
public class MyHttpModule : IHttpModule
{
public void Init(HttpApplication context)
{
var dependency = (IDependency)context.Context.Items["dependency"];
// consume dependency...
}
public void Dispose()
{
}
}
アンドレイ・ツィクノフの答えに興味がありますが、コメントする担当者がいません。
私は 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; }
}