结构图是否允许您以惰性方式进行构造函数注入(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/

10-11 21:07