结构图,带有插件列表的构造函数

And*_*asN 12 .net c# structuremap

我有这样的界面

public interface IWriter
{
  ...
}
Run Code Online (Sandbox Code Playgroud)

和一个班级

public class WriterMerger
{
  public WriterMerger(IEnumerable<IWriter> writers)
  ...
}
Run Code Online (Sandbox Code Playgroud)

我希望structuremap用WriterMerger填充所有已注册的IWriter的构造函数参数.我注册了不同的作家

StructureMap.ObjectFactory.Initialize(x =>
{
  x.ForRequestedType<IWriter>().AddConcreteType<MemoryWriter>();
  x.ForRequestedType<IWriter>().AddConcreteType<FlatFileWriter>();
  x.ForRequestedType<IWriter>().AddConcreteType<DbWriter>();
}
Run Code Online (Sandbox Code Playgroud)

但是打电话

ObjectFactory.CreateInstance<WriterMerger>();
Run Code Online (Sandbox Code Playgroud)

返回异常"没有为PluginFamily System.Collections.Generic.IEnumerable`1 [[IWriter ..]]"定义的默认实例(已编辑类名)

自动执行此操作的任何技巧?或者我是否必须制作自定义工厂方法?

Evi*_*ndy 18

实际上这可以在不改变构造函数的情况下完成

将容器配置更改为:

StructureMap.ObjectFactory.Initialize(x =>
{
    x.Scan(scan =>
    {
        scan.TheCallingAssembly();
        scan.AddAllTypesOf<IWriter>();
    });
    x.ForRequestedType<IEnumerable<IWriter>>()
        .TheDefault.Is.ConstructedBy(x => ObjectFactory.GetAllInstances<IWriter>());
});
Run Code Online (Sandbox Code Playgroud)


Jos*_*gan 10

如果希望注入类型的所有具体实例,则必须将参数声明为数组.您可以通过将构造函数更改为:

public WriterMerger(IWriter[] writers)
Run Code Online (Sandbox Code Playgroud)

请注意,像ReSharper这样的代码清理工具可能会突出显示构造函数中的数组,并建议您使用IEnumerable替换它,如果这是WriterMerger所需的全部内容.但是,这些工具不了解StructureMap使用数组的要求,因此您必须忽略它.

您可能也有兴趣知道您可以自动注册所有IWriters,而不是明确列出它们.只需将容器配置更改为:

StructureMap.ObjectFactory.Initialize(x =>
{
    x.Scan(scan =>
    {
        scan.TheCallingAssembly();
        scan.AddAllTypesOf<IWriter>();
    });
});
Run Code Online (Sandbox Code Playgroud)

扫描有许多不同的选项,允许您扫描不同的程序集,排除某些类型等.