StructureMap:创建为瞬态(每个请求)不起作用

我正试图解决一个IoC问题,起初看起来很容易,但结果却是一个痛苦的屁股:-P

我有一个重量级的主类,必须初始化一次,所以它被标记为Singleton。 但是,这个类使用的子类必须为每个请求创建一次,因此它被标记为Transient:

public class MyRegistry : Registry { public MyRegistry() { For() .Singleton() .Use(ctx => new MainClass(() => ctx.GetInstance())); For() .Transient() .Use(ctx => CreateNewInstanceOfSubClass()); } private ISubClass CreateNewInstanceOfSubClass() { return new SubClass(); } } public interface ISubClass { } public class SubClass : ISubClass { } public interface IMainClass { } public class MainClass : IMainClass { private readonly Func _subClassProvider; public MainClass(Func subClassProvider) { _subClassProvider = subClassProvider; } public void DoStuff() { var requestSpecificInstanceOfSubClass = _subClassProvider(); // ... } } 

如您所见,我将lambda传递给MainClass的构造函数,该构造函数用于获取ISubClass的实例。 在调试期间,我肯定会看到每次MainClass需要SubClass实例时MainClass执行ctx.GetInstance() 。 但令我惊讶的是, SubClass只创建一次作为单例,而不是为每个请求创建。

但是,当我直接从我的代码中的某个地方调用container.GetInstance() ,行为完全符合要求。 SubClass为每个请求创建一次且仅创建一次。

我不太确定,但我猜这个问题来自传递给lambda的上下文对象,它是单例(?)的上下文。 但我真的不知道如何在这里得到理想的行为!?

我希望你能帮我这个。 谢谢你的回答。

此致,但丁

看来你需要重新设计一下。 为了避免使用强制依赖 ,您需要为图的根对象提供比其任何依赖项更短(或相等)的生命周期。

一种选择是创建第三类来管理MainClassSubClass之间的交互。

接口

 public interface IInteractionManager { void DoStuff(); } public interface IMainClass { void DoStuff(ISubclass subclass); } public interface ISubClass { } 

 public class InteractionManager : IInteractionManager { private readonly IMainClass mainClass; private readonly ISubClass subClass; public InteractionManager( IMainClass mainClass, ISubClass subClass) { this.mainClass = mainClass; this.subClass = subClass; } public void DoStuff() { this.mainClass.DoStuff(this.subClass); } } public class MainClass : IMainClass { public void DoStuff(ISubclass subclass) { // do something with transient subclass } } public class SubClass : ISubClass { } 

注册处

 public class MyRegistry : Registry { public MyRegistry() { // The root of the object graph is transient... For() .Transient() .Use(); // ...therefore, it can have transient dependencies... For() .Transient() .Use(); // ...and singleton dependencies. For() .Singleton() .Use(); } } 

这很正常。

因为你在Main类中解析ISubclass是单例。

当Main Class解决时,它将获得一个Subclass并且它们将一起生活(它们必须因为main是singlenton)。

当你解决时,你应该检查第一个父生命周期,如果它是单身,你有每个请求或每个依赖关系无关紧要,它将与单身一起生活。

如果您确实需要MainClass成为长期存在的对象,但每个请求使用一个新的SubClass对象,您可以:

1.)将一个自定义Func实例注册到容器,或注册到MainClass本身,该代理将委托给根容器本身。 请记住,您也可以使用自动布线,因此您不必全部内联。

2.)将IContainer本身注入MainClass,并将其用作服务定位器,在每次请求期间懒惰地检索新的ISubClass。

使用IContext将无法正常工作,因为IContext与原始请求相关联。 StructureMap中的“瞬态”实际上意味着“按请求”,因此当您将Func注入到委托给原始IContext的单例中时,每次都会得到完全相同的ISubClass。 有关生命周期的更多信息,请参见http://structuremap.github.io/object-lifecycle/ 。

我是SM的作者btw。