Dependency injection DI和运行时参数-structuremap

Dependency injection DI和运行时参数-structuremap,dependency-injection,structuremap,Dependency Injection,Structuremap,我越来越多地发现自己在混合运行时参数和隐式构造注入,这对我来说很难闻 示例-我有一个描述过滤器的基类,以及特定过滤器的各种继承类型(标记、类别、日期、作者等) var filter=StructureMap.ObjectFactory .With(“caption”).EqualTo(“按标记筛选的帖子:”) .带有(“参数”)。相等(参数) .With(“displayInSummary”).EqualTo(true) .GetInstance(); 我这样做的原因是因为在构造函数中我有一个

我越来越多地发现自己在混合运行时参数和隐式构造注入,这对我来说很难闻

示例-我有一个描述过滤器的基类,以及特定过滤器的各种继承类型(标记、类别、日期、作者等)

var filter=StructureMap.ObjectFactory
.With(“caption”).EqualTo(“按标记筛选的帖子:”)
.带有(“参数”)。相等(参数)
.With(“displayInSummary”).EqualTo(true)
.GetInstance();
我这样做的原因是因为在构造函数中我有一个接口,我希望StructureMap使用该接口注入一个具体类(IArticleConfigurator):

public TagListFilter(字符串标题、IDictionary参数、bool显示摘要、iArticleConfiguration配置程序)
:base(标题、参数、显示摘要、配置程序)
但我突然想到,我用一个具体的类而不是接口替换了一个简单的构造函数,本质上是相同的,只是使用DI注入了一个具体的类型。我这样做是因为目前我们的配置在一个xml文件中,但将被移动到CMS,所以使用接口似乎是个好主意

这似乎是错误的,不符合DI的精神


我应该使用工厂生成各种过滤器吗?如果是这样,我仍然可以利用DI来获得iArticleConfiguration的具体实例吗?

您不应该将参数从一个依赖项显式地传递到另一个依赖项,或者至少应该尽量减少它们的数量。使用参数解析实例的一大缺点是将参数名称指定为字符串文字,这使得在更改构造函数签名时代码非常脆弱

我可能想到的一个例子(请注意,我对您的域和实体的责任一无所知)是注入提供者,或者,正如您已经说过的,注入工厂。例如,创建类似于
ItaglistfilterConfiguration Provider
(您应该根据需要更改名称,我只是想给您一些动力)。如果过滤器的参数相同,可以使用以下三种方法创建非常抽象的提供程序,如
IFilterConfigurationProvider

interface ITagListFilterConfigurationProvider
{
    string Caption { get; }
    IDictionary<string,string> GetParameters();
    bool IsDisplayInSummary { get; }
}
您所需要的只是实现它(因为您正在将具体参数传递给构造函数),并将此行为提取给提供者。剩下的就是向StructureMap注册具体的提供程序,并在不传递任何具体参数的情况下解析过滤器

var filter = StructureMap.ObjectFactory.GetInstance<TagListFilter>();
var filter=StructureMap.ObjectFactory.GetInstance();

我总是不太愿意在接口中放置属性(例如,不是做东西的方法),但我现在经常看到这种情况,所以我想我现在会更频繁地这样做。这种方法很有效,非常感谢你,Ilya。作为后续,在使用继承结构时,我还将使用聚合器服务来减少构造函数接口参数。请参阅blog.ploeh.dk/2010/02/02/RefactoringToAggregateServices.aspx
interface ITagListFilterConfigurationProvider
{
    string Caption { get; }
    IDictionary<string,string> GetParameters();
    bool IsDisplayInSummary { get; }
}
public TagListFilter(ITagListFilterConfigurationProvider configurationProvider, IArticleConfigurator configurator)
var filter = StructureMap.ObjectFactory.GetInstance<TagListFilter>();