解决方法
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>的“greediest”构造函数并且定居在公共懒惰(Func< T> valueFactory,bool isThreadSafe)上.由于我们没有告诉它如何处理布尔的isThreadSafe参数,它会在尝试解析“懒惰”时抛出异常.
Lazy的文档指出,默认的Lazy(Func< T> valueFactory)构造函数的“线程安全模式”是LazyThreadSafetyMode.ExecutionAndPublication,它只是通过将true传递到上面的构造函数的isThreadSafe参数来实现.所以,如果我们可以告诉StructureMap对isThreadSafe来说是真的,那么我们会得到一样的行为,就像我们首先调用我们实际想要使用的构造函数一样(例如Lazy(Func< T> valueFactory)).
简单地注册x.For(typeof(bool)).使用(y => true)将是非常鲁莽和危险的,因为我们将告诉StructureMap继续使用任何布尔值的值true.相反,我们需要告诉StructureMap为这个一个布尔参数使用什么值,我们可以这样做.
x.For(typeof(Lazy<>)).Use(typeof(Lazy<>)) .CtorDependency<bool>("isThreadSafe").Is(true);
当解析Lazy< T>时,StructureMap现在知道使用isThreadSafe参数的“true”值.我们现在可以使用Lazy< T>在构造函数的参数,并得到我相信你正在寻找的行为.
您可以更详细地阅读懒惰课程here.