结构图是否允许您以惰性方式进行构造函数注入(inject)?
意思是不创建要使用的注入(inject)对象?
最佳答案
更新: StructureMap v3开箱即用地实现了此功能,因此不再需要此技巧。
StructureMap版本2并没有,但是通过一些技巧,您可以使它完成我认为您要寻找的事情。首先,您已经可以手动连接Lazy<T>
实例,如下所示:
container = new Container(x =>
{
x.Scan(y =>
{
y.TheCallingAssembly();
y.WithDefaultConventions();
});
x.For<Lazy<IFoo>>().Use(y => new Lazy<IFoo>(y.GetInstance<Foo>));
x.For<Lazy<IBar>>().Use(y => new Lazy<IBar>(y.GetInstance<Bar>));
x.For<Lazy<IBaz>>().Use(y => new Lazy<IBaz>(y.GetInstance<Baz>));
});
这很好用,但是您必须分别注册每种类型。如果您可以利用更多基于约定的方法,那就更好了。理想情况下,以下语法会很好。
x.For(typeof(Lazy<>)).Use(typeof(Lazy<>));
这种语法实际上有效。不幸的是,在运行时,StructureMap将尝试为
Lazy<T>
查找“最贪婪”的构造函数,并根据public Lazy(Func<T> valueFactory, bool isThreadSafe)
进行设置。由于我们没有告诉它如何处理boolean isThreadSafe参数,因此它在尝试解析“Lazy”时将抛出异常。Lazy的文档指出,默认
Lazy(Func<T> valueFactory)
构造函数的“线程安全模式”是LazyThreadSafetyMode.ExecutionAndPublication
,恰好是通过将true传递给上述构造函数的isThreadSafe参数获得的结果。因此,如果我们仅告诉StructureMap将true
传递给isThreadSafe
,我们将得到与最初调用实际要使用的构造函数相同的行为(例如Lazy(Func<T> valueFactory)
)。简单地注册
x.For(typeof(bool)).Use(y => true)
将会非常鲁and和危险,因为我们将告诉StructureMap继续进行下去,并将true
值用于任何位置的 bool 值。相反,我们需要告诉StructureMap仅将此一个 bool 参数使用什么值,我们可以像这样进行操作。x.For(typeof(Lazy<>)).Use(typeof(Lazy<>))
.CtorDependency<bool>("isThreadSafe").Is(true);
现在,StructureMap知道在解析
Lazy<T>
时将isThreadSafe参数的值设置为true。现在,我们可以在构造函数参数中使用Lazy<T>
,并获得我认为您正在寻找的行为。您可以更详细地阅读有关Lazy类的信息here。
关于c# - Structuremap是否开箱即用支持Lazy?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/6811956/