【问题标题】:Ninject (IoC) and an alternative to a factory with conditional logicNinject (IoC) 和具有条件逻辑的工厂的替代方案
【发布时间】:2013-10-18 23:54:12
【问题描述】:

我遇到了一个我想用 Ninject 解决的场景,但到目前为止,我的所有工作都没有遇到过这种情况。

WCF 服务应用程序

W3C 日志解析应用程序(出于演示目的过于简单化)。

由 W3CLogItem 实现的 IW3CLogItem W3CLogItem 有一个 IUrlData 类型的公共成员(包含重要数据,但可以是 5 个具体实现之一,具体取决于它包含的内容)。

使用哪个具体实现取决于字符串匹配,其构造函数采用正则表达式模式,它将用于解析数据以及要解析的字符串。

目前我有一个简单的工厂来进行字符串比较,然后调用 Create() 来返回一个新的具体对象(DocumentUrlItem、DriverUrlItem、AssetUrlItem 等...)。

我正在查看 wiki 文档以及如何命名绑定,但即使这样也只能让我了解一半。

我的问题是:这可以在没有工厂的情况下完成吗?我能否以某种方式在绑定(即 .contains 等)上放置一个条件属性,该属性评估为 true 以知道要使用哪个绑定,或者我最好还是坚持使用工厂?

让我们详细说明一下。

如果我以简化的方式编写不带ninject 的工厂,它将如下所示:

protected IUrlData Create(string urldata)
{
    if (urldata.Contains("bob"))
    {
        return new BobUrlData(urldata)
    }
    else if (urldata.Contains("tim"))
    {
        return new TimUrlData(urldata);
    }  
}

注意几点:

1) 实现 IUrlData 的类的数量会随着时间的推移而增长。字符串“tim”和“bob”将来自数据库。

2) 传递给 BobUrlData 和 TimUrlData 的 urldata 不是现实世界中唯一的参数,还会有一个正则表达式(也来自数据库,它由知道如何处理该特定的条目时间戳计算)随着时间的推移进入。

3) 我真的很好奇这是否可以使用 Ninject 来完成,而不需要一起使用工厂,以某种方式通过元数据或名称实现相同的工作,但全部通过绑定,同时保持代码可扩展但只读(除了绑定模块)。

【问题讨论】:

    标签: c# dependency-injection inversion-of-control ninject


    【解决方案1】:

    您可以使用 Ninject 绑定到方法。

    Ninject Wiki - Contextual Binding

    如果您设置了返回所需内容的方法,则不再需要工厂。我不能说一个比另一个更好,因为它们都可以工作,但我确实更喜欢工厂做这项工作并拥有 Ninject 访问权限,以便为我提供正确的实现。你的结果最终还是一样。

    另外,在同一页面的正上方是Specifying Constraints

    【讨论】:

    • 我已经阅读了所有文档和大约 15 个其他站点,并且 .When() 不断出现。我很难理解如何让 IParameter 参与解决问题。基本上它归结为我需要弄清楚(如果可能的话)是如何评估构造函数中的一个参数来决定使用哪个绑定。这是我的意思的一个例子:stackoverflow.com/questions/15267368/…
    【解决方案2】:

    从纯粹的角度来看,抽象工厂是从对象的接口中抽象出实现的正确方法。话虽如此,ninject 提供了多种方式来实现您想要的,而无需使用抽象工厂。我觉得最能帮助你的是ToMethodproviders

    【讨论】:

    • Nicolas,我听到了,也许我的回答是将抽象工厂转移到它自己的组件中。本质上,我想要实现的(可能超出我选择的 IoC 容器的范围)是能够放入一个实现 IUrlData 的新库,而无需重新编译整个项目。我的 Ninject 绑定模块已经分离出来,所以如果我可以通过框架轻松实现这一点,那将是双赢的。然而,通过移动抽象工厂的位置可以实现相同的行为。
    • 我的观点是,无论您使用抽象工厂还是 ninject 的内置方法,您都依赖于相同的模式(提供者基本上是抽象工厂,而 ToMethod 绑定是工厂方法)。但是,使用 ninject 时,每次更改依赖项之一时都必须重新编译组合根。如果您希望能够在不重新编译项目的情况下更改依赖项,则必须查看支持在 app.config 文件中配置依赖项解析的 DI 容器。大多数 DI 容器都这样做,但不是 ninject。
    • castle windsor 是最杰出的 DI 容器之一,它支持通过 app.config 进行配置。它也是最成熟的框架之一,并且支持许多高级 DI 构造,例如条件绑定和拦截
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多