簡體   English   中英

你是如何制作通用通用工廠的?

[英]How do you make a Generic Generic Factory?

我正在開發一個webmethod集合的客戶端(Silverlight)接口。 我試圖避免為每個web方法編寫任何自定義代碼。 所以我創建了一個ServiceCall<TResult>來處理每個調用, TResult指定了服務的返回類型(我使用XmlSerializer來創建返回的實例)。 客戶端類公開了與每個web方法匹配的函數,該函數所要做的就是創建ServiceCall<TResult>的新實例,並將TResult指定為方法的預期返回類型。 這很好用。

我也在使用Ninject (依賴注入器)來嘗試保持一切獨立。 Ninject支持開放式泛型,這對我的ServiceCall<TResult>非常有用。

但這也意味着我正在注入對Ninject容器的引用。 它隱藏了綁定到容器的ServiceCall<TResult>的依賴性。 所以我想注入一個工廠來創建我的ServiceCall<TResult>實例。 這並不棘手,但我想把它變成一個通用的通用工廠。 意思是我希望有一個類似Factory<T<>>東西,它有一個方法public T<TU> Createinstance<TU>()

但我不知道如何創建一個類型參數的泛型類,它本身就是一個開放的genric。

它是.Net中的事件嗎? - 或者我是否必須創建特定的ServiceCallFactory?

編輯:我正在使用接口的接口,但沒有必要將它們混合到這里的問題,所以我編輯了這個問題。

回應Timwi:使用依賴注入(DI)的常用方法是將接口綁定到您的實現,只有容器知道這些綁定。 然后,您將對代碼進行編碼。 這帶來了許多優點。 比我在這里提到的更多。
無論如何,它還排除了靜態類(因為那將是對特定類的依賴)。 相反,我將指示容器(在這種情況下為Ninject)始終為工廠界面提供相同的實例,以類似行為的方式。
這排除了public static class Factory<T>選項,因為它是靜態的,如果它不是靜態的,我現在需要使用的每種類型的T,都有點挫敗了泛型類的目的。
建議使用具有“完全通用”方法的非泛型類(如我傳遞ServiceCall<MyResult>而不僅僅是MyResult ),這或多或少是我現在所做的(減去靜態類部分)。 Ninject容器有一個Get方法,就像你的第二個建議一樣。
這個問題有兩部分; 首先它使我的代碼直接依賴於一個容器(Ninject),但這對我來說並不是那么大的問題。 令我惱火的是,如果你從外面看我的客戶,你只會看到對Ninject的依賴。 你不會知道,直到你運行嘗試打電話,客戶需要在Ninject注冊的ServiceCall的實現工作。
但是如果Client構造函數采用了Factory>類型的參數,那么它會更加清晰。

在任何情況下,我認為這將是一個常見的問題,所以要么有一個共同的解決方案,或者它不是一個常見的問題,我試圖做一些愚蠢的事情;)我仍然不是那種依賴注入,所以這可能非常情況就是這樣。

這是你在尋找什么: 通用工廠模式

namespace GenericFactoryPatternTestApp
{
    public class Factory< T >
    {
        private readonly Dictionary< string, Type > _factoryDictionary = new Dictionary< string, Type >();

        public Factory()
        {    
            Type[] types = Assembly.GetAssembly(typeof (T)).GetTypes();

            foreach (Type type in types)
            {
                if (!typeof (T).IsAssignableFrom(type) || type == typeof (T))
                {
                    // Incorrect type
                    continue;
                }

                // Add the type
                _factoryDictionary.Add(type.Name, type);
            }
        }

        public T Create< V >(params object[] args)
        {
            return (T) Activator.CreateInstance(_factoryDictionary[typeof (V).Name], args);
        }
    }
}

所以,如果我理解你的話,你會有一個看起來像這樣的課:

public static class Factory<T<>>
{
    public static T<TU> CreateInstance<TU>() { /* ... */ }
}

然后你會怎么稱呼它? 像這樣?

var myServiceCall = Factory<ServiceCall<>>.CreateInstance<MyResult>();

什么阻止你簡單地宣布像這樣的工廠......

public static class Factory<T>
{
    public static T CreateInstance() { /* ... */ }
}

... 或這個 ...

public static class Factory
{
    public static T CreateInstance<T>() { /* ... */ }
}

...然后像這樣生成你的實例?

var myServiceCall = Factory<ServiceCall<MyResult>>.CreateInstance();
var myServiceCall = Factory.CreateInstance<ServiceCall<MyResult>>();

我很抱歉,如果我愚蠢,但我可能需要知道Ninject如何工作以及它如何讓你進入工廠。

暫無
暫無

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

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