【问题标题】:Should I make an IUnityContainer object use a Singleton pattern?我应该让 IUnityContainer 对象使用单例模式吗?
【发布时间】:2009-02-17 16:36:17
【问题描述】:

我不熟悉使用 Unity 和 IoC/DI 概念。我通过 James Kovacs 在dnrTV 上的节目在测试中推出了我自己的概念来开始这个概念。

他的示例将容器作为单例运行,通过 IoC 类中的静态方法访问,因此您可以在启动时注册类型并在整个应用程序中解析类型。

我知道这不是全功能,主要是展示 IoC 的概念。

我现在正尝试在项目中使用 Unity。

在我的 Main() 中,我创建了一个新容器,但是一旦我的 WinForms 打开,该容器就会超出范围并被丢弃。稍后在程序中,当我尝试解析类型时,我不再拥有原始容器及其注册类型。

是否有我遗漏的概念或实现构造?

我目前的想法是创建这样的东西:

public static class Container
{
    private static readonly object syncRoot = new object();
    private static volatile IUnityContainer instance;

    public static IUnityContainer Instance
    {
        get
        {
            if (instance == null)
            {
                lock (syncRoot)
                {
                    if (instance == null)
                    {
                        instance = new UnityContainer();
                    }
                }
            }
            return instance;
        }
    }
}

我很确定这会起作用,只是看起来不太对。

【问题讨论】:

    标签: inversion-of-control singleton unity-container


    【解决方案1】:

    出于同样的原因,我使用静态类 - 以避免它超出范围。

    我对您所做的一个区别是,我包装了所有统一调用并添加检查以查看统一是否已配置,您将在此处看到:

    using System.Configuration;
    using Microsoft.Practices.Unity;
    using Microsoft.Practices.Unity.Configuration;
    
    namespace Utilities
    {
        public static class ServiceLocator
        {
            private static IUnityContainer container = new UnityContainer();
            private static bool isConfigured;
    
            public static void Clear()
            {
                container = new UnityContainer();
            }
    
            private static IUnityContainer Container
            {
                get
                {
                    if (!isConfigured)
                    {
                        ConfigureContainer();
                    }
                    return container;
                }
            }
    
            public static T Resolve<T>()
            {
                return Container.Resolve<T>();
            }
    
            public static T Resolve<T>(string name)
            {
                return Container.Resolve<T>(name);
            }
    
            public static void AddInstance<T>(object instance)
            {
                Container.RegisterInstance(typeof (T), instance);
            }
    
            private static void ConfigureContainer()
            {
                    UnityConfigurationSection section = (UnityConfigurationSection) ConfigurationManager.GetSection("unity");
                    section.Containers.Default.Configure(container);
                    isConfigured = true;        
            }
        }
    }
    

    【讨论】:

    • 谢谢,我没有在静态类中配置我的容器。我认为这使我可以灵活地在测试情况下更改配置,而无需在测试中使用“生产”配置时自动注入。
    • 很公平。当然,通过单元测试,你不应该真的需要容器。不过,我理解集成测试场景中的需求。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-05-09
    • 2013-10-29
    • 2011-04-12
    • 1970-01-01
    • 2014-09-20
    相关资源
    最近更新 更多