我一直在研究在我的 Web 应用程序中实现 IoC 的细节,但以一种利用 Microsoft.Practices.ServiceLocation 的方式。我专门使用 Autofac 和 asp.net 集成,但我想让自己对其他容器开放。按照这个问题,我担心如何在我的网络应用程序代码中访问容器。
我有一个“核心”库,主要定义要解析的接口。我的网络应用程序和其他应用程序也使用这个核心库。定义通用接口非常方便。我认为这是一个访问 IoC 容器的好地方,我使用静态类做到了这一点。诀窍是将容器注入静态类。
在 Web 环境中这很棘手,因为每个请求的容器可能不同,而在非 Web 应用程序中,它可能一直都是相同的。起初我尝试使用一种方法直接注入容器,但在下一个 Web 请求中很快就失败了!所以我想出了这个:
public static class IoCContainer
{
public static void SetServiceLocator(Func<IServiceLocator> getLocator)
{
m_GetLocator = getLocator;
}
static private Func<IServiceLocator> m_GetLocator = null;
public static T GetInstance<T>(string typeName)
{
return m_GetLocator().GetInstance<T>(typeName);
}
}
现在在我的 global.asax.cs 我这样做:
protected void Application_Start(object sender, EventArgs e)
{
var builder = new Autofac.Builder.ContainerBuilder();
... register stuff ...
var container = builder.Build();
_containerProvider = new Autofac.Integration.Web.ContainerProvider(container);
Xyz.Core.IoCContainer.SetServiceLocator(() =>
new AutofacContrib.CommonServiceLocator.AutofacServiceLocator
(_containerProvider.RequestContainer));
}
public IContainerProvider ContainerProvider
{
get { return _containerProvider; }
}
static IContainerProvider _containerProvider;
解决依赖的呼吁看起来像
var someService = Xyz.Core.GetInstance<ISomeService>();
因此,我没有传递一个特定的容器,而是传递一个知道如何获取容器的委托。对于非 Web 应用程序,委托可能只会返回 builder.Build() 提供的内容。
我对专家的问题是,这有意义吗?我有一种简单的方法可以解决依赖关系,而无需知道容器产品是什么或容器本身来自何处。你怎么看?