ArrayMap的数组构造函数依赖项

时间:2009-11-01 17:18:03

标签: c# dependency-injection structuremap

我在ITask

中定义了一些TaskRegistry个混凝土类型
public class TaskResigstry : Registry
{
    public TaskResigstry()
    {
        ForRequestedType<IBootstrapperTask>().TheDefaultIsConcreteType<StartTasks>();

        ForRequestedType<ITask>().TheDefaultIsConcreteType<FirstTask>();
        ForRequestedType<ITask>().AddConcreteType<SecondTask>();
        ForRequestedType<ITask>().AddConcreteType<ThirdTask>();
    }
}

我的StartTasks

public class StartTasks : IBootstrapperTask
{
    public StartTasks(ITask[] tasks)
    {
        foreach(var task in tasks)
        {
            task.Run();
        }
    }
}

如何使用StructureMap注入ITask[]构造函数参数?

感谢。

3 个答案:

答案 0 :(得分:3)

如果你想注入一个数组,那么在流畅的界面中有一个方法......

ForRequestedType<IBootStrapperTask>().TheDefault.Is.OfConcreteType<StartTasks>()
     .TheArrayOf<ITask>().Contains(
            y => {
                y.OfConcreteType<Task1>();
                y.OfConcreteType<Task2>();
                y.OfConcreteType<Task3>();
            });

如果你想在你的构造函数中接受一个IEnumerable<T>的路线,就我所知,事情开始变得有点复杂。您可以像这样指定和构建构造函数参数: -

ForRequestedType<IBootStrapperTask>().TheDefault.Is.OfConcreteType<StartTasks>()
            .CtorDependency<IEnumerable<ITask>>().Is(i => {
                i.Is.ConstructedBy(c => {
                    return new List<ITask> { 
                           c.GetInstance<Task1>(), 
                           c.GetInstance<Task2>(), 
                           c.GetInstance<Task3>()
                    };
                });
            });

如果你想要所有已注册的类型,你可以创建一个自定义IBuildInterceptor,通过BuildSession上的CreateInstanceArray方法访问所有已注册的类型,但我觉得我可能会走错路。

我很乐意纠正这个更容易:)。

答案 1 :(得分:3)

您无需再做任何事情。只需要一个IBootstrapperTask的实例,所有ITasks都会被自动注入。

var container = new Container(x => x.AddRegistry<TaskResigstry>());
var bootstrapper = container.GetInstance<IBootstrapperTask>();

注意:StructureMap只能识别用于注入多个实例的数组 - 更改构造函数以获取IEnumerable或强类型集合。

作为一种快捷方式,如果您想在程序集中注入所有ITask实例,而无需手动注册所有这些实例,则可以将注册表更改为:

public class TaskResigstry : Registry
{
    public TaskResigstry()
    {
        ForRequestedType<IBootstrapperTask>().TheDefaultIsConcreteType<StartTasks>();

        Scan(x =>
        {
            x.TheCallingAssembly();
            x.AddAllTypesOf<ITask>();
        });
    }
}

答案 2 :(得分:1)

接受的答案很好,但语法已过时。以下是执行相同操作的新语法:

this.For<IBootStrapperTask>().Use<StartTasks>()
    .EnumerableOf<ITask>().Contains(x =>
    {
        x.Type<Task1>();
        x.Type<Task2>();
        x.Type<Task3>();
    });

StructureMap很棒,但我常常因缺乏使用最新语法的示例而感到沮丧。