zac*_*cko 5 c# structuremap dependency-injection ioc-container
我正在尝试解决 IoC 问题,一开始看起来很简单,但结果却很痛苦:-P
我有一个重量级主类,它必须只初始化一次,因此它被标记为单例。然而,该类使用一个必须为每个请求创建一次的子类,因此它被标记为 Transient:
public class MyRegistry : Registry
{
public MyRegistry()
{
For<IMainClass>()
.Singleton()
.Use(ctx => new MainClass(() => ctx.GetInstance<ISubClass>()));
For<ISubClass>()
.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<ISubClass> _subClassProvider;
public MainClass(Func<ISubClass> subClassProvider)
{
_subClassProvider = subClassProvider;
}
public void DoStuff()
{
var requestSpecificInstanceOfSubClass = _subClassProvider();
// ...
}
}
Run Code Online (Sandbox Code Playgroud)
如您所见,我将 lambda 传递给 的构造函数MainClass,该构造函数用于获取 的实例ISubClass。在调试过程中,我绝对可以看到ctx.GetInstance<ISubClass>()每次MainClass需要SubClass实例时都会执行该操作。但令我惊讶的是,SubClass它仅作为单例创建一次,而不是为每个请求创建。
但是,当我container.GetInstance<ISubClass>()直接从代码中的某个位置调用时,行为完全符合预期。SubClass对于每个请求仅创建一次。
我不太确定,但我猜问题来自于传递给 lambda 的上下文对象,它是单例(?)的上下文。但我真的不知道如何在这里获得所需的行为!?
我希望你能帮我解决这个问题。感谢您的回答。
问候,但丁
看来你需要稍微修改一下设计。为了避免存在强制依赖项,您需要为图的根对象提供比其任何依赖项更短(或相等)的生命周期。
MainClass一种选择是创建一个第三类来管理和之间的交互SubClass。
public interface IInteractionManager
{
void DoStuff();
}
public interface IMainClass
{
void DoStuff(ISubclass subclass);
}
public interface ISubClass
{ }
Run Code Online (Sandbox Code Playgroud)
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
{ }
Run Code Online (Sandbox Code Playgroud)
public class MyRegistry : Registry
{
public MyRegistry()
{
// The root of the object graph is transient...
For<IInteractionManager>()
.Transient()
.Use<InteractionManager>();
// ...therefore, it can have transient dependencies...
For<ISubClass>()
.Transient()
.Use<SubClass>();
// ...and singleton dependencies.
For<IMainClass>()
.Singleton()
.Use<MainClass>();
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
3518 次 |
| 最近记录: |