我一直在研究在我的Web应用程序中实现IOC的细节,但以一种利用microsoft.practices.servicelocation的方式。我专门使用autopac和ASP.NET集成,但我想让自己打开其他容器。沿着
this question
,我担心如何访问我的Web应用程序代码中的容器。
我有一个“核心”库,它主要定义要解析的接口。这个核心库也被我的Web应用程序和其他应用程序使用。定义公共接口非常方便。我认为这是一个很好的地方,可以访问IOC容器,我用了一个静态类来实现这一点。技巧是将容器注入静态类。
在Web环境中,这是很棘手的,因为容器对于每个请求可能是不同的,而在非Web应用程序中,容器可能总是相同的。起初,我尝试用一个方法注入容器direclty,但在下一个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()提供的服务。
我要问的是,这有道理吗?我有一个简单的方法可以解决依赖关系,而不知道容器产品是什么或者容器本身来自哪里。你怎么认为?