2009-07-05 54 views
6

对不起,如果这是一个非常基本的问题,但它真的让我很开心。我非常喜欢DI的想法,这对我的测试确实有帮助,但我想我已经碰到了一堵砖墙。所以,我有两种类型:DI对象图建筑 - 分离逻辑和构造图

Table 
TableManager 

现在的表对象都有这样就可以构造:

Table(ITableCommandRunner tableRunner, 
     IQueryProvider queryProvider, 
     IDataReader reader, 
     string Name) 

现在的表对象几乎只使用这些对象,以便以下是你要求的规则你需要什么我将它们传入。现在我的TableManager对象用于打开和关闭等表。它唯一需要的是一个ITableCommandRunner,所以我在构造函数中传递它。

TableManager(ITableCommandRunner tablrunner) 

好这很好,但在TableManager.OpenTable命令我必须呼吁ITableCommandRunner打开表条命令,然后建立一个新的表对象传回。

public ITable OpenTable(string tableName) 
    { 
     // Call open table command on tablerunner. 
     // I need a IQueryProvider and IDataReader to pass to the table. 
     return new Table<TEntity>(this.tablerunner, provider,reader, tableName); 
    } 

但现在在我的开放表命令我必须做一个IDataReader和IQueryProvider。如果我将它们传递给TableManager的构造函数,这并不违反“仅仅将对象传递给内部类型而不真正使用它们”。

我不太确定我是如何做到这一点的。任何人都可以帮助我吗?

我只是不知道如何分开对象结构和逻辑。

回答

2

一个选项是配置一个TableFactory其中确实知道查询提供者和读者,并且只需要知道表名。然后,您可以将工厂传递给TableManager。另一方面,TableManager听起来像它可能需要是工厂本身 - 在这种情况下,它简单确实需要提供者和读者,即使它可能不明显开始,因为它只是通过它们。

我同意它有点混乱 - 基本上,如果“深入树中”(和动态创建)需要一条信息,那么任何创建它的东西都需要这些信息 - 并且创建该创建者需要的信息等等。如果你不小心(有时甚至是你),它肯定会变成一团糟。

根据您的DI框架,您可能能够在容器中配置一个类似工厂的对象,然后要求在执行时创建一个新实例。这意味着你的代码会与DI框架相结合 - 这是一个波动和环岛的例子。基本上信息必须是某处,并且当你需要时,你总是需要有一些“引用链”来获取它。

遗憾没能在其上具有更愉快的前景,但即使这些想法不帮你了,至少你知道你并不孤单:)

+0

我想我可能只需要在管理器中使用IQueryProvider和IDataReader。表管理器几乎只是一个名称不同的工厂。我观看了DI与MiškoHevery的谷歌技术演讲,并且同意他所说的话,但我永远无法找到任何现实世界中我所处境况的例子。说“不要仅仅通过对象就好了”他们失望“,但没有一个例子,这意味着什么。我正在开发SDK,因此每个部分都需要独立。 – 2009-07-05 08:27:35

0

您可以加入providerreader作为参数上OpenTable()

谁在打电话OpenTable()?来电者是否知道providerreader,以便它可以将它们传递给该方法?