问题描述
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 没有,但是通过一些技巧,您可以让它完成我相信您正在寻找的事情.首先,您已经可以像这样手动连接 Lazy<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 将尝试为 Lazy<T>
找到最贪婪"的构造函数并选择 public Lazy(Func<T> valueFactory, bool isThreadSafe)
.由于我们没有告诉它如何处理布尔 isThreadSafe 参数,所以当它尝试解析 `Lazy' 时会抛出异常.
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'.
Lazy 的文档指出默认 Lazy(Func<T> valueFactory)
构造函数的线程安全模式"是 LazyThreadSafetyMode.ExecutionAndPublication
,它就是这样发生的通过将 true 传递给上面构造函数的 isThreadSafe 参数来得到什么.因此,如果我们可以告诉 StructureMap 为 isThreadSafe
传递 true
,我们将获得与调用我们真正想要首先使用的构造函数相同的行为(例如 Lazy(Func
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(bool)).Use(y => true)
会非常鲁莽和危险,因为我们会告诉 StructureMap 继续使用值 true
for any 布尔值.相反,我们需要告诉 StructureMap 对于这个 one 布尔参数使用什么值,我们可以这样做.
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 现在知道在解析 Lazy<T>
时使用 isThreadSafe 参数的true"值.我们现在可以在构造函数参数中使用 Lazy<T>
,并获得我认为您正在寻找的行为.
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.
您可以在此处详细了解 Lazy 类.
You can read about the Lazy class in more detail here.
这篇关于Structuremap 是否支持开箱即用的 Lazy?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!