2011-07-25 36 views
2

望着这answer on SO,我有点在下面的“原则”困惑:依赖注入 - 正确的地方注入

应用好莱坞原则

好莱坞原则DI方面说:不要拨打DI Container,它会给你打电话。

千万不要直接通过调用 代码中的容器来请求依赖关系。通过使用构造器注入隐式地询问它。

但是如果我在我的DAL的存储库类,我想这种情况下提供给当TCP/IP客户端连接其上创建一个对象?我应该在什么地方进行注射?

现在,我有这样的事情:

// gets created when a new TCP/IP client is connected 
class Worker 
{ 
    private readonly IClient client; 
    public Worker(IClient client) 
    { 
     // get the repository 
     var repo = IoC.GetInstance<IClientMessagesRepo>(); 

     // create an object which will parse messages 
     var parser = new MessageParser(client); 

     // create an object which will save them to repo 
     var logger = new MessageLogger(parser, repo); 
    } 
} 

我当我的应用程序启动明显不能创建实例。那么我在哪里注入回购?

非常感谢!

+0

当应用程序被启动为什么不能创建IClientMessageRepo实例?从给出的代码,它远不是'明显的'... –

+0

你可能也想引用这个答案:http://stackoverflow.com/questions/1410719/design-where-should-objects-be-registered-when -using-windsor/1410738#1410738 –

+0

@Mark:不,对不起,我的意思是,我不能要求容器在开始时创建* Worker *实例。我*可以*创建回购实例,然后传递它,但我使用一个回购每个实体,所以我觉得传递一堆比使用容器来根据需要获取它们更复杂。 – doe

回答

1

您应该努力只呼叫IoC.GetInstance()一次。

既然你不能在启动时创建的工人,你应该建立WorkerFactory并有DI容器注入的依赖成:

public class WorkerFactory 
{ 
    private readonly IClientMessagesRepo clientMessagesRepo; 
    public WorkerFactory(IClientMessagesRepo clientMessagesRepo) 
    { 
     this.clientMessagesRepo = clientMessagesRepo; 
    } 

    public Worker Create(IClient client) 
    { 
     return new Worker(client, clientMessagesRepo); 
    } 
} 
0

移动IClientMessagesRepo到您的构造函数的参数:

public Worker(IClient client,IClientMessagesRepo clientMessagesRepo) 

现在当然这只是把问题移到了一下,到创建工人的地步。当然,有时需要调用IoC容器。但在这些情况下,我宁愿传入容器中的参数,而不是从静态属性中访问它。或者使用某种工厂。

+0

但我该如何解决这种类型如果只有repo界面在我的IoC上注册?我正在使用(或更好的,滥用)StructureMap。 (并将容器作为参数传递是另一种违反“最佳实践”的行为) – doe

0

在有你的论点IClientMessagesRepo,并让国际奥委会填补你:

public Worker(IClient client, IClientMessagesRepo repo)  
{ 
    [...] 
} 

很显然,你的构造应该做一点不仅仅能创建几个局部变量,但你的想法。

0

据我所知你在IOC容器中有储存库,但没有IClient。假设你有访问的时候你创建工人阶级IOC容器,并假设你正在使用StructureMap你可以写:

IClient concreteClient = ...; 
worker = container.Using<IClient>(concreteClient).GetInstance<Worker>(); 

这样,你告诉StructureMap使用特定IClient实例,但获得存储库中的其他依赖项。

注意:自从我上次使用StructureMap以来有一段时间,所以也许代码不是100%正确的,但概念在那里,您可以在创建组件时提供具体的依赖关系。