是否Structuremap支持延迟开箱?Structuremap

2023-09-03 03:20:23 作者:ぢ 丢掉

请问structuremap让你做的构造函数注入一个懒惰的方式? 这意味着不产生被注入,直到它被使用的对象

Does structuremap allow you to do constructor injection in a lazy fashion? Meaning not creating the object which is injected until it is used?

推荐答案

更新: StructureMap V3实现这个开箱即用,所以这一招不再需要

UPDATE: StructureMap v3 implements this out of the box, so this trick is no longer necessary.

StructureMap 2版没有,但有一些技巧可以得到它做你在找什么,我相信了。首先,你已经可以连线了延迟< T> 情况下,手动像这样的:

StructureMap version 2 doesn't, but with a few tricks you can get it to do what I believe you are looking for. First of all, you can already wire up Lazy<T> instances manually like this:

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>));
});

这工作得很好,但你必须分别注册每个类型。这将是更好,如果你可以采取更习惯为基础的方法的优势。理想情况下,下面的语法将是很好。

This works just fine, but you have to register each and every type individually. It would be nicer if you could take advantage of a more convention-based approach. Ideally, the following syntax would be nice.

x.For(typeof(Lazy<>)).Use(typeof(Lazy<>));

本语法实际工作......一些。不幸的是,在运行时,StructureMap将尝试找到贪婪构造延迟&LT; T&GT; 并定居在公共懒(Func键&LT; T&GT; valueFactory ,布尔isThreadSafe)。由于我们没有告诉它做什么用布尔isThreadSafe参数,就会当它试图解决'懒'抛出异常。

This syntax actually works... somewhat. Unfortunately, at runtime, StructureMap will attempt to find the "greediest" constructor for Lazy<T> and settle on public Lazy(Func<T> valueFactory, bool isThreadSafe). Since we didn't tell it what to do with the boolean isThreadSafe parameter, it will throw an exception when it tries to resolve `Lazy'.

该文档懒惰指出默认的线程安全模式懒(Func键&LT; T&GT; valueFactory)构造函数是 LazyThreadSafetyMode.ExecutionAndPublication ,这恰好是你通过传递true到上面的构造函数的isThreadSafe参数得到。因此,如果我们能告诉StructureMap通过 isThreadSafe ,我们会得到相同的行为,如果我们所谓的我们其实是想构造函数首先使用(例如:懒(Func键&LT; T&GT; valueFactory))。

The documentation for Lazy states that the "thread safety mode" of the default Lazy(Func<T> valueFactory) constructor is LazyThreadSafetyMode.ExecutionAndPublication, which just so happens to be what you get by passing true into the isThreadSafe parameter of the constructor above. So, if we could just tell StructureMap to pass true for isThreadSafe, we would get the same behavior as if we called the constructor we actually wanted to use in the first place (e.g. Lazy(Func<T> valueFactory)).

简单地注册 x.For(typeof运算(布尔))使用(Y =&GT;真)将是非常鲁莽和危险的,因为我们会告诉StructureMap去继续并使用值的任何的布尔任何地方。相反,我们需要告诉StructureMap用于眼前这个的一个的布尔参数,我们可以这样做什么样的价值。

Simply registering x.For(typeof(bool)).Use(y => true) would be very reckless and dangerous since we would be telling StructureMap to go ahead and use the value true for any boolean anywhere. Instead, we need to tell StructureMap what value to use for just this one boolean parameter, which we can do like this.

x.For(typeof(Lazy<>)).Use(typeof(Lazy<>))
 .CtorDependency<bool>("isThreadSafe").Is(true);

现在StructureMap知道解析时使用的真实价值为isThreadSafe参数延迟&LT; T&GT; 。现在,我们可以使用延迟&LT; T&GT; 在构造函数中的参数,并获得该行为,我相信你正在寻找

StructureMap now knows to use the value of "true" for the isThreadSafe parameter when resolving Lazy<T>. We can now use Lazy<T> in constructor parameters, and get the behavior I believe you were looking for.

您可以更详细地了解懒惰类这里。

You can read about the Lazy class in more detail here.