我有一个自定义HTTP模块。我想用我的IoC框架注入记录器,这样我就可以在模块中记录错误。然而,当然我没有得到一个构造函数,所以不能将它注入到构造函数中。什么是最好的方式去做这件事?IoC依赖注入到自定义HTTP模块 - 如何? (ASP.NET)
如果您需要特定的IoC容器 - 我目前使用的是Windsor,但可能会很快转移到AutoFac。
谢谢
我有一个自定义HTTP模块。我想用我的IoC框架注入记录器,这样我就可以在模块中记录错误。然而,当然我没有得到一个构造函数,所以不能将它注入到构造函数中。什么是最好的方式去做这件事?IoC依赖注入到自定义HTTP模块 - 如何? (ASP.NET)
如果您需要特定的IoC容器 - 我目前使用的是Windsor,但可能会很快转移到AutoFac。
谢谢
见你可以在需要的依赖通过由init方法传递给你的HttpApplication的情况下通过......
public class MyHttpModule : IHttpModule
{
public void Init(HttpApplication context)
{
var dependency = (IDependency)context.Context.Items["dependency"];
// consume dependency...
}
public void Dispose()
{
}
}
-1,因为很难用这种方式嘲笑依赖关系 – 2009-11-03 15:48:42
@Mauricio Scheffer:也许,但随后只是将模块实现为卑微的可执行文件。我更喜欢使用静态注入的方法。人们认为它有助于可测性,但它确实伤害了它。 – 2009-11-03 16:22:12
在这种情况下,Humble Executable当然可以很好地工作,我会将该信息添加到答案中。但是,你可以吃你的蛋糕,也可以吃它,看看我的解决方案。 – 2009-11-03 16:41:34
第一次见到依赖注入的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访问根容器。
这是相当有限的,不能做构造函数注入。 – 2010-10-07 20:38:18
我很想知道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; }
}
您在这里没有执行依赖注入,您正在执行服务位置。 – 2010-10-07 20:40:02
看起来像你有rep事物排序:P – 2014-09-20 07:47:08
你可以使用一个服务定位器,看看这个问题:([依赖注入和服务定位器模式之间的不同] http://stackoverflow.com/questions/1557781/ what-the-the-difference-between-dependency-injection-and-service-locator-patter) – FinnNk 2009-11-01 16:00:21