2012-04-05 120 views
0

在Kozmic的博客(2009年)上,他建议通用工厂从容器中检索物体。那么,这对我来说就像是一个伪服务定位器。所以我想问一下这里的专家的意见。Castle Windsor Generic Typed Factory

public interface IGenericFactory 
    { 
     T Create<T>(); 
    } 

我可以用它从Windsor容器中取物件吗?这种方法有什么缺点吗?

更新:

其实,我想用它来获取我不想创建多个工厂只有几个瞬间。所有这些场景都有一个工厂。

回答

1

我做了快速谷歌搜索,发现这篇文章,你可能指的是:http://kozmic.pl/2009/12/23/castle-typed-factory-facility-reborn/

如果是这样的话,那么基耶斯洛夫Koźmic说,它自己:

[...]你可以用它来建立一个通用服务定位器

是的,现在Service Locator is considered to be an anti-pattern

但是,文章是关于例外的情况。笔者把它相当清楚地第一段:

使用IoC容器时,一般的经验法则是 - 当你在你的组件引用您的容器(外的任何地方你的引导代码)你这样做错误。与所有规则一样,有例外,但它们很少见。

+0

@ w0lf-使用通用工厂方法,我不必在我的代码中引用容器。我把它注册为一个打字工厂和繁荣。注入工厂并获得您想要的任何东西! (实际上,我想用它来获取我不想创建多个工厂的几个瞬变)。我想确定这是好事还是坏事? – user1178376 2012-04-18 21:45:51

+0

@ user1178376该方法的问题在于它实际上是一个抽象服务定位器,可以轻松隐藏类的依赖关系。为了避免这种情况及其引起的维护问题,请尝试使用普通的构造函数注入和专门的工厂。 – GolfWolf 2012-04-19 07:02:20

+1

另请注意Nicholas Blumhardt的评论。他非常清楚地描述了这一点:“它可以尝试创建字面上的任何东西 - 这会使维护和测试变得更加困难。” – Steven 2013-07-12 11:45:07

1

相反,考虑以下因素:

public interface IGenericFactory<out T> 
{ 
    T Create(); 
} 

接口只需要创建一次,但必须注射每次需要解决的服务。这样,它不是一个通用的服务定位器(这是一个反模式,正如前面提到的w0lf)。

加分点:

普通的依赖注入,需要在你的依赖关系图中的所有服务都可以解决。 IGenericFactory<>将通过打字的工厂设施自动解决。但是它的泛型类型参数在执行Create()之前不会被解决。

如果这种情况发生在程序深处的边缘情况下,并且您忘记注册该服务,那么在生产之前您可能没有意识到该错误。

解决的办法是编写一个IGenericFactory<>的自定义解析器,它检查泛型类型参数是否有一个处理程序,并且它没有等待任何依赖项被注册。有关自定义解析器的信息在这里:http://docs.castleproject.org/Windsor.Resolvers.ash