簡體   English   中英

中央靜態類的這種實現是否正確?

[英]Is this implementation of a central static class correct?

因此,我正在啟動一個新項目,嘗試實施過去幾年中我學到的一些知識,其中第一件事是使用Castle for IoC。

我想要一個中心的“核心”課程,該課程可以在眾多最終項目(控制台應用程序,網站)之間共享。 所以我想,這里有兩個問題:

a)這種方法正確嗎?b)我的實施方法正確嗎?

我知道這是一門很小的課程,但是我想從一開始就弄正確。

public static class Global {
        static IWindsorContainer _Container;
        static int ContainerInitalised = 0;
        static string ServicesFile;

        public static IWindsorContainer Container{
            get{
                if (Interlocked.CompareExchange(ref ContainerInitalised, 1, 0) == 0) {
                    Collection<IWindsorInstaller> installers = new Collection<IWindsorInstaller> {
                        { FromAssembly.InDirectory(new AssemblyFilter("Installers")) }
                    };
                    if (!String.IsNullOrWhiteSpace(ServicesFile)) {
                        installers.Add(Configuration.FromXmlFile(ServicesFile));
                    }
                    _Container = new WindsorContainer().Install(installers.ToArray());
                }
                return _Container;
            }
        }

        public static void Initialise(string servicesFile) {
            ServicesFile = servicesFile;
        }

    }

按照David的說法,您的想法是轉向ServiceLocator解決方案,這是使用IoC容器的最糟糕的方法。

同樣,使用通用接口抽象IoC容器也是一個壞主意,因為您最終失去了特殊的容器功能:特別是,沒有公開釋放方法的接口會導致使用成熟的IoC容器(如基於RRR模式的windosr)導致災難。

Krzysztof在他的NDC演講中已經清楚地描述了正確的方法

  • 根據MVC3實施,使用工廠將IoC容器插入您的應用程序
  • 僅盡快執行一個解決:針對非Web應用的單個解決,針對Web場景的每個請求一個解決
  • 始終發布您解決的問題

通過邁向“服務定位器”實施,您也許可以稍微清理一下。 (實際上,有一個通用庫可以完全做到這一點。)

例如,您可以在接口后面抽象IoC容器,並擁有一個提供當前實現的靜態工廠(以替換通用的Global類並使其更具針對性)。 像這樣:

public interface IoCContainer
{
    object GetInstance(Type serviceType);
    object GetInstance(Type serviceType, string key);
    IEnumerable<object> GetAllInstances(Type serviceType);
    T GetInstance<T>();
    T GetInstance<T>(string key);
    IEnumerable<T> GetAllInstances<T>();
}

public static class IoCContainerFactory
{
    private static IoCContainer current;

    public static IoCContainer Current
    {
        get
        {
            if (current == null)
                throw new DomainException("IoC Container Not Initialized.  This application must call a bootstrap method in an IoC implementation project.");
            return current;
        }
    }

    public static void Initialize(IoCContainer container)
    {
        current = container;
    }
}

然后在另一個項目中,我實現IoCContainer接口(我使用StructureMap,您使用Castle ...有很多選擇)。 同樣在另一個項目中,我有一個Initializer類,該類將引導容器實現(因為任何實現的配置都不同),最后,初始化此“全局”工廠:

IoCContainerFactory.Initialize(new IoCContainerImplementation(ObjectFactory.Container));

(在上面的代碼行中, IoCContainerImplementation是我對上述接口的實現,而ObjectFactory來自StructureMap,並且在此代碼之前的代碼行中進行了配置/引導。)

當然,使用這種方法需要權衡一些。 通過在通用接口后面抽象我的IoC容器,我只能執行許多IoC容器實現中的通用操作。 對於我的需求,我只想調用一個方法來解決依賴關系。 但是,其他一些事情,例如用屬性裝飾類/屬性(如果您選擇的IoC容器具有該功能),則可能需要緊密耦合到該特定容器,或者需要擴展此實現以包括以某種方式使用該功能的自定義屬性。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM