在单身人士背后提取IoC容器 – 做错了吗?

通常,我喜欢让应用程序完全不知道IoC容器。 但是我遇到了需要访问它的问题。 为了消除痛苦,我使用了一个基本的单身人士。 在你跑山或拉出霰弹枪之前,让我回顾一下我的解决方案。 基本上,IoC单例绝对没有任何东西,它只是委托给必须传入的内部接口。我发现这使得使用Singleton减少痛苦。

下面是IoC包装器:

public static class IoC { private static IDependencyResolver inner; public static void InitWith(IDependencyResolver container) { inner = container; } /// Container has not been initialized. Please supply an instance if IWindsorContainer. public static T Resolve() { if ( inner == null) throw new InvalidOperationException("Container has not been initialized. Please supply an instance if IWindsorContainer."); return inner.Resolve(); } public static T[] ResolveAll() { return inner.ResolveAll(); } } 

的IDependencyResolver:

 public interface IDependencyResolver { T Resolve(); T[] ResolveAll(); } 

到目前为止我已经取得了很大的成功,我曾经几次使用它(也许每一个项目,我真的不想一直使用它),因为我可以注入任何我想要的东西:Castle,Stub,fakes,等等

这是一条湿滑的路吗? 我是否会遇到潜在的问题?

我已经看到,即使Ayende在Rhino Commons代码中实现了这种模式,但我建议不要在任何可能的情况下使用它。 Castle Windsor默认没有此代码是有原因的。 StructureMap确实如此,但Jeremy Miller一直在远离它。 理想情况下,您应该将容器本身视为与任何全局变量一样多的怀疑。

但是,作为替代方法,您始终可以配置容器以将IDependencyResolver解析为对容器的引用。 这可能听起来很疯狂,但它更灵活。 只记住一个对象应该称为“新”或执行处理的经验法则,但不能同时记住两者。 对于“call new”替换为“解析引用”。

那不是真正的单身人士课程。 这是一个静态成员的静态类。 是的,这似乎是一个很好的方法。

我认为JP Boodhoo甚至有这个模式的名称。 静态网关模式 。

请注意:Microsoft模式和实践已经创建了一个公共服务定位器( http://www.codeplex.com/CommonServiceLocator ),大多数主要IoC容器将在不久的将来实现。 您可以开始使用它而不是IDependencyResolver。

顺便说一句:这是解决问题的常用方法,效果很好。

这一切都取决于用法。 使用这样的容器称为服务定位器模式。 在某些情况下,它不适合以及适用的情况。

如果你谷歌“服务定位模式”你会看到很多博客post说它是一个反模式,但事实并非如此。 该模式已被过度使用(/滥用)。

对于典型的业务线应用程序,您不应在隐藏依赖项时使用SL。 您还遇到了另一个问题:如果您使用根容器(而不是其中一个生命周期),则无法管理状态/生命周期。

服务定位器非常适合基础设施。 例如,ASP.NET MVC使用Service Locator能够解析每个控制器的所有依赖关系。