Structuremap在Singleton模式下返回多个实例

6

我已经使用命名实例为同一个接口注册了5个派生类。所有这些类都被注册为单例。

For<IBaseInterface>().Singleton().Use<DerivedClass1>().Named("Derived1");
For<IBaseInterface>().Singleton().Use<DerivedClass2>().Named("Derived2");
For<IBaseInterface>().Singleton().Use<DerivedClass3>().Named("Derived3");

有一个静态类,根据输入解析实例。然而,我观察到每次调用ObjectFactory.GetInstance都会返回新的实例,而不是单例。应用程序中也没有线程。

你有什么想法吗?为什么会这样?

编辑:

静态解析助手会导致任何问题吗?这是我解析实例的方式。在示例应用程序中,单例正常工作,但在我的机器上无法工作。

添加一些细节 - 项目是MVC Web API,并在本地IIS上进行测试。我确信应用程序中没有用户创建的线程。

public static class Resolver
{
    public static IBaseInterface GetHelper(string inputParam)
    {
        if inputParam is "Case1"
            return ObjectFactory.GetInstance<IBaseInterface>("Derived1")
        //Similarly for other instances
    }
}

1
我无法重现你的结果。我执行了你的注册并尝试了GetInstanceGetNamedInstance两种方法。每次调用GetInstance都会返回最后注册的实例。而每次调用GetNamedInstance("Derived1")都会返回相同的DerivedClass1实例。 - PHeiberg
是的,请发布一个能够重现问题的示例。 - neontapir
嗨,PHeiberg和neontapir,我尝试创建了一个简单的代码示例,并且它在其中运行良好。但是在我的应用程序中它不起作用。我添加了一些关于如何调用实例的详细信息。你们能否请检查一下。谢谢。 - ganeshran
1
你在哪里使用解析器(resolver)?同时请注意ASP.NET应用程序是通过设计实现多线程的。 - Ikaso
1个回答

1
我建议您小心使用依赖注入容器。例如,您在帖子中展示的Resolver类,它只是作为一种工厂或提供程序吗?
在使用依赖注入时,您需要确保遵循RRR模式:注册,解析和释放。注册应该发生在应用程序的组合根中。对于ASP.Net MVC,通常在Global.asax中的代码后台的Application_Start方法中进行。这应该仅在每个应用程序池启动(对于IIS)时发生一次。
如果您碰巧在传递容器(或实例化容器并执行注册和稍后的解析的对象) - 您不应该这样做 - 那么您看到的这些“不同实例”可能来自两个不同的容器。即使您没有传递容器,如果您在某个地方实例化容器,以便在每个请求之后,容器被垃圾回收并在随后的请求中重新创建,则可能会看到单例对象的“不同实例”被解析和实例化; 再次,每个都来自容器的不同实例。您可以验证的一种方式是验证从容器中解析的对象也来自同一个容器实例。
希望对您有所帮助。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接