C# Ninject(IoC)和具有条件逻辑的工厂的替代品

C# Ninject(IoC)和具有条件逻辑的工厂的替代品,c#,dependency-injection,inversion-of-control,ninject,C#,Dependency Injection,Inversion Of Control,Ninject,我遇到了一个我想用Ninject解决的场景,但到目前为止,我用它所做的工作都没有遇到过这种情况 WCF服务应用程序 W3C日志解析应用程序(出于演示目的过于简单) 由W3CLogItem实现的IW3CLogItem W3CLogItem有一个类型为IUrlData的公共成员(包含重要数据,但可以是5种具体实现之一,具体取决于它包含的内容) 使用哪个具体实现的决定基于字符串匹配,其构造函数采用正则表达式模式来解析数据和要解析的字符串 目前,我有一个简单的工厂,它进行字符串比较,然后调用Create

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

WCF服务应用程序

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

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

使用哪个具体实现的决定基于字符串匹配,其构造函数采用正则表达式模式来解析数据和要解析的字符串

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

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

我的问题是:没有工厂能做到这一点吗?我是否可以在计算结果为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实现这一点,而无需将工厂放在一起,通过元数据或名称以某种方式实现相同的工作,但全部通过绑定,同时让代码保持可扩展但只读(绑定模块除外)。

您可以使用Ninject绑定到方法

如果您设置了返回所需内容的方法,则不应该再需要工厂。虽然我不能说其中一个比另一个好,因为它们都能工作,但我更喜欢工厂来做这项工作,并且有那个访问对象来给我正确的实现。你的结果最终还是一样的


同样,在同一页的正上方是。

从纯粹主义的角度来看,抽象工厂是从对象接口抽象出实现的正确方法。有鉴于此,ninject提供了各种方法来实现您想要的内容,而无需使用抽象工厂。我觉得对您帮助最大的是,我已经阅读了所有文档和大约15个其他网站,.When()不断出现。我很难理解如何让IParameter参与解决问题。归根结底,我需要弄清楚(如果可能的话)如何计算构造函数中的一个参数来决定使用哪个绑定。这是我的意思的一个例子:Nicolas,我听到了,也许我的答案是将抽象工厂转移到它自己的装配厂。从本质上说,我试图实现的(可能是我选择的IoC容器的过度使用)是能够插入一个实现IUrlData的新库,而无需重新编译整个项目。我的Ninject绑定模块已经被分离出来了,所以如果我能够通过框架轻松实现这一点,那将是一个双赢的结果。但是,通过移动抽象工厂的位置可以实现相同的行为。我的观点是,无论您使用抽象工厂还是ninject的内置方法,您都依赖于相同的模式(提供者基本上是抽象工厂,而ToMethod绑定是工厂方法)。但是,使用ninject,每次更改一个依赖项时,都必须重新编译合成根。如果您希望能够在不重新编译项目的情况下更改依赖项,则必须查看一个DI容器,该容器支持在app.config文件中配置依赖项解析。大多数DI容器都会这样做,但ninject除外。castle windsor是支持通过app.config进行配置的最著名的DI容器之一。它也是最成熟的框架之一,支持许多高级DI构造,如条件绑定和拦截