StructureMap:创建瞬态(每个请求)不工作 [英] StructureMap: Creation as Transient (per request) not working

查看:223
本文介绍了StructureMap:创建瞬态(每个请求)不工作的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图解决一个IoC的问题,这似乎很容易在第一,但竟然是在屁股:-P痛

I'm trying to solve a IoC problem, that seemed easy at first, but turned out to be a pain in the ass:-P

我有一个重量级主类,它必须因此它标记为辛格尔顿只初始化一次。然而,这种类使用,必须为每个请求创建一次一个子类,因此它被标记为瞬态:

I have a heavy weight main class, which must be initialized only once, so it's marked as Singleton. However this class uses a subclass which must be created once for each request, so it's marked as 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();

        // ...
    }
}

正如你所看到的,我通过lambda来 MainClass ,这是用来获得 ISubClass 。在调试过程中我肯定可以看到 ctx.GetInstance< ISubClass>()每次执行 MainClass 需要 SubClass中实例。但让我惊讶的是, SubClass中只创建一次作为一个单身,而不是为每个请求创建。

As you can see, I pass a lambda to the constructor of MainClass, which is used to get an instance of ISubClass. During debugging I could definitely see that ctx.GetInstance<ISubClass>() is executed each time MainClass needs a SubClass instance. But to my surprise, SubClass is only created once as a singleton, instead of being created for each request.

然而,当我打电话 container.GetInstance< ISubClass>()直接从什么地方我的代码中是完全一样的期望的行为。创建一次且仅一次为每个请求 SubClass中

However, when I call container.GetInstance<ISubClass>() directly from somewhere within my code the behavior is exactly as desired. SubClass is created once and only once for each request.

我不是十分清楚,但我猜问题来自上下文对象时,传递给拉姆达,这是一个单例的上下文(?)。但我真的不知道怎么在这里得到所需的行为!?

I'm no quite sure, but I guess the problem comes from the context object, that is passed to the lambda, which is the context of a singleton(?). But I really don't know how to get the desired behavior here!?

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

I hope you can help me with this one. Thanks for your answers.

问候,
但丁

推荐答案

看来你需要重新修改设计的一点点。为了避免俘虏依赖的,你需要给的根对象图较短(或等于)寿命比它的任何依赖。

It seems that you need to rework the design a little. To avoid having captive dependencies, you need to give the root object of the graph a shorter (or equal) lifetime than any of its dependencies.

一个选择是做一个第三类来管理之间的相互作用MainClass SubClass中

One option would be to make a 3rd class to manage the interaction between MainClass and SubClass.

public interface IInteractionManager
{ 
    void DoStuff();
}

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

public interface ISubClass
{ }





Classes

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
{ }



注册表



Registry

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>();
    }
}

这篇关于StructureMap:创建瞬态(每个请求)不工作的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆