Structuremap 是否支持开箱即用的 Lazy?
结构图是否允许您以惰性方式进行构造函数注入? 意思是在使用之前不创建注入的对象?
Does structuremap allow you to do constructor injection in a lazy fashion?
Meaning not creating the object which is injected until it is used?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
更新: StructureMap v3 开箱即用地实现了此功能,因此不再需要此技巧。
StructureMap 版本 2 没有,但通过一些技巧,您可以让它完成我相信您正在寻找的事情。首先,您已经可以像这样手动连接 Lazy实例:
这工作得很好,但您必须单独注册每个类型。如果您可以利用更加基于约定的方法,那就更好了。理想情况下,以下语法会很好。
这种语法确实有效......有点。不幸的是,在运行时,StructureMap 将尝试为
Lazy
找到“最贪婪”的构造函数,并选择public Lazy(FuncvalueFactory, bool isThreadSafe)
。由于我们没有告诉它如何处理布尔 isThreadSafe 参数,因此当它尝试解析“Lazy”时会抛出异常。Lazy 的文档指出,默认的 Lazy(FuncvalueFactory) 构造函数的“线程安全模式”是 LazyThreadSafetyMode.ExecutionAndPublication,这恰好是您可以通过将 true 传递给上面构造函数的 isThreadSafe 参数来获得。因此,如果我们可以告诉 StructureMap 为
isThreadSafe
传递true
,我们将获得与调用我们实际上想要首先使用的构造函数相同的行为(例如Lazy(FuncvalueFactory)
)。简单地注册 x.For(typeof(bool)).Use(y => true) 会非常鲁莽和危险,因为我们会告诉 StructureMap 继续并使用值
true
任何地方的 any 布尔值。相反,我们需要告诉 StructureMap 对于这个一个布尔参数使用什么值,我们可以这样做。StructureMap 现在知道在解析,并获得我相信您正在寻找的行为。
Lazy
时对 isThreadSafe 参数使用“true”值。我们现在可以在构造函数参数中使用 Lazy您可以在此处详细了解 Lazy 类。
UPDATE: StructureMap v3 implements this out of the box, so this trick is no longer necessary.
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: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.
This syntax actually works... somewhat. Unfortunately, at runtime, StructureMap will attempt to find the "greediest" constructor for
Lazy<T>
and settle onpublic 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'.The documentation for Lazy states that the "thread safety mode" of the default
Lazy(Func<T> valueFactory)
constructor isLazyThreadSafetyMode.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 passtrue
forisThreadSafe
, 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)
).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 valuetrue
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.StructureMap now knows to use the value of "true" for the isThreadSafe parameter when resolving
Lazy<T>
. We can now useLazy<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.
是的,确实如此。最新版本的 StructureMap (2.6.x) 是针对 .NET Framework 3.5 编译的,因此无法访问 .NET 4 中引入的
Lazy
类型。但是,它确实支持相同的功能 - “在使用之前不创建注入的对象”。您不再依赖Lazy
,而是依赖Func
。无需特殊集装箱注册。我提供了一个示例程序,该程序创建以下输出:
Sample.cs:
Yes, it does. The latest version of StructureMap (2.6.x) is compiled against .NET Framework 3.5, and so does not have access to the
Lazy<T>
type introduced in .NET 4. However, it does support the same functionality - "not creating the object which is injected until it is used". Instead of depending on aLazy<T>
, you depend on aFunc<T>
. No special container registration is required.I've included a sample program that creates the following output:
Sample.cs: