我有一个自定义的HTTP模块。我想使用我的IoC框架注入记录器,以便可以记录模块中的错误。但是,由于没有构造函数,所以无法将其注入到其中。有什么最好的方法来解决这个问题?
如果您需要特定的IoC容器-我目前正在使用Windsor,但可能很快会转到AutoFac。
谢谢
我有一个自定义的HTTP模块。我想使用我的IoC框架注入记录器,以便可以记录模块中的错误。但是,由于没有构造函数,所以无法将其注入到其中。有什么最好的方法来解决这个问题?
如果您需要特定的IoC容器-我目前正在使用Windsor,但可能很快会转到AutoFac。
谢谢
我第一次在Spring.NET中看到了将依赖注入到HttpModules中。这个想法是有一个特殊的HttpModule,它将依赖注入到其他应用程序级别的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; }
}
}
在web.config中注册HttpModuleInjectionModule应该在其他HttpModule之前:
<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>
我相信你可以在Windsor中做类似的事情。不同之处在于你如何从HttpModuleInjectionModule访问你的根容器。
public class MyHttpModule : IHttpModule
{
public void Init(HttpApplication context)
{
var dependency = (IDependency)context.Context.Items["dependency"];
// consume dependency...
}
public void Dispose()
{
}
}
我对andrey-tsykunov的回答很好奇,但是我没有足够的声望去评论它。
我试着熟悉控制反转(IoC)和依赖注入(DI),所以我可能还有什么不理解的地方,但是使用IContainerProviderAccessor在MyModule内部会比创建另一个模块更简单,不是吗?
例如:
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; }
}