我在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[]
构造函数参数?
感谢。
答案 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很棒,但我常常因缺乏使用最新语法的示例而感到沮丧。