【发布时间】:2014-09-19 21:35:46
【问题描述】:
在旧的 Asp.NET webforms 应用程序中,我尝试注入一些 IOC。
我不会详细介绍,但对于这个,我认为 ServiceLocator 是一个很好的工具。 我知道服务定位器是一种反模式;o)
根据文档https://github.com/autofac/Autofac/wiki/Common-Service-Locator,ServiceLocator 配置如下:
var container = builder.Build();
var csl = new AutofacServiceLocator(container);
ServiceLocator.SetLocatorProvider(() => csl);
问题是 LoacatorProvider 是用根容器设置的。所以,生命周期管理是不活跃的。
我正在想办法解决这个问题
因为ServiceLocator.SetLocatorProvider 将委托作为参数,并且因为每次调用ServiceLocator.Current 都会调用此委托,所以为什么不为每个请求提供一个 AutofacServiceLocator 实例。
public class Global : HttpApplication, IContainerProviderAccessor
{
// Provider that holds the application container.
static IContainerProvider _containerProvider;
void Application_Start(object sender, EventArgs e)
{
// Code that runs on application startup
RouteConfig.RegisterRoutes(RouteTable.Routes);
BundleConfig.RegisterBundles(BundleTable.Bundles);
_containerProvider = new ContainerProvider(AutoFacBootstrapper.CreateContainer());
ServiceLocator.SetLocatorProvider(() =>
{
AutofacServiceLocator asl = HttpContext.Current.Items["AutofacServiceLocator"] as AutofacServiceLocator;
if (asl == null)
{
var cpa = (IContainerProviderAccessor)HttpContext.Current.ApplicationInstance;
var cp = cpa.ContainerProvider.RequestLifetime;
asl = new AutofacServiceLocator(cp);
HttpContext.Current.Items["AutofacServiceLocator"] = asl;
}
return asl;
});
}
public IContainerProvider ContainerProvider
{
get { return _containerProvider; }
}
}
此代码似乎有效。 IDisposable 对象在请求结束时被释放。 InstancePerRequest配置没问题。
此实现是否存在任何问题(性能、内存...)?
【问题讨论】:
-
你还在用这种方法吗?我们遇到了类似的问题。
-
事实上,我计划在一个尚未准备好接受纯 ioc 糖的遗留网络表单应用程序中使用这种方法。我只是问这样走行不行。
-
猜这是一个不可能的问题;)我们做了一些非常相似的事情 - 将定位器提供程序设置为从根容器解析服务的 func,然后根据子范围提供适当的服务定位器。它尚未投入生产,但在分析时,它似乎解决了我们看到的内存泄漏问题(无法使用任何开箱即用的解决方案,因为我们需要在同一应用程序中对 WCF 和 MVC 进行生命周期管理)
标签: asp.net webforms autofac lifetime