2011-12-02 18 views
1

我想爲我的服務工廠和道工廠製造一些通用工廠,並且遇到一些限制。當需要依賴注入時,通用工廠是不可能的?

通常我的服務和DAO工廠是這樣的:

public static class PersonServiceFactory 
{ 
    private static PersonService personService; 

    public static PersonService GetInstance() 
    { 
     if (personService == null) 
     { 
      PersonDao personDao = PersonDaoFactory.GetInstance(); 
      personService = new PersonService(personDao); 

     } 

     return personService; 
    } 
} 

public static class PersonDaoFactory 
{ 
    private static PersonDao personDao; 

    internal static PersonDao GetInstance() 
    { 
     if (personDao == null) 
     { 
      personDao = new PersonDao(); 

     } 

     return personDao; 
    } 
} 

然後我試圖做一個普通的工廠:

public abstract class EntityDaoFactory<daoClass> 
     where daoClass : class, new() 
    { 
     private static daoClass factorySupportClass; 

     internal static daoClass GetInstance() 
     { 
      if (factorySupportClass == null) 
      { 
       factorySupportClass = new daoClass(); 

      } 

      return factorySupportClass; 
     } 
    } 

    public abstract class EntityServiceFactory<serviceClass, daoClass> 
     where serviceClass : class, new() 
     where daoClass : class 
    { 
     private static serviceClass factorySupportClass; 

     internal static serviceClass GetInstance() 
     { 
      if (factorySupportClass == null) 
      { 
       //daoClass daoSupportClass = *how to get daoSupportClassfactory.GetInstance(); here?* 
       factorySupportClass = new serviceClass(daoSupportClass); 

      } 

      return factorySupportClass; 
     } 
    } 

這樣他們就可以像這樣使用:

public static class PersonDaoFactory : Entities.EntityDaoFactory<PersonDao> 
{ 
} 

public static class PersonServiceFactory : Entities.EntityServiceFactory<PersonService, PersonDaoFactory> 
{ 
} 

下面是我遇到的問題:

  1. 不能使用靜態類作爲泛型的類型約束,我試圖用於EntityServiceFactory,因爲沒有它,我不知道如何注入適當的dao。

  2. 不能有工廠從通用工廠得到,因爲我得到一個錯誤,如:

靜態類的Persons.PersonDaoFactory'不能 從 類型派生「Entities.EntityDaoFactory」 。 靜態類必須從對象派生。

  1. 試圖使他們所有的非靜態類與私人建設者要解決這個問題,但後來我得到:

「Persons.PersonService」必須是一個非抽象類用爲了在通用類型或方法 使用它作爲參數 「服務類」公共 參數構造「Entities.EntityServiceFactory

我能讀出爲什麼3號在這裏出現,但這仍然不能解決我的問題。我得到了DaoFactory的工作,但只有在特定的DaoClass不需要任何依賴注入的情況下才有效,否則會再次彈出錯誤3。

反正讓這些普通的工廠使用了不同的方法,同時仍然能夠使用DI工作?

編輯----

我能得到這種工作的,但是它有一些古怪。首先,我創建了一個IEntityFactory接口:

public interface IEntityFactory<T> 
    where T : class 
{ 
    T GetInstance(); 
} 

再變EntityDaoFactory到:

public abstract class EntityDaoFactory<daoClass> : IEntityFactory<daoClass> 
     where daoClass : class, new() 
    { 
     private static daoClass factorySupportClass; 

     public daoClass GetInstance() 
     { 
      if (factorySupportClass == null) 
      { 
       factorySupportClass = new daoClass(); 

      } 

      return factorySupportClass; 
     } 
    } 

所以,我可以通過在適當的類型參數,改變EntityServiceFactory到:

public abstract class EntityServiceFactory<serviceClass, daoClass, daoFactoryClass> 
     where serviceClass : class, new() 
     where daoClass : class, new() 
     where daoFactoryClass : IEntityFactory<daoClass>, new() 
    { 
     private static serviceClass factorySupportClass; 

     public static serviceClass GetInstance() 
     { 
      if (factorySupportClass == null) 
      { 
       daoFactoryClass daoSupportFactory = new daoFactoryClass(); 
       daoClass daoSupportClass = daoSupportFactory.GetInstance(); 
       factorySupportClass = new serviceClass(); 

      } 

      return factorySupportClass; 
     } 
    } 

所以對於特定的實現,例如Person對象,調用如下所示:

public class PersonDaoFactory : Entities.EntityDaoFactory<PersonDao> 
{ 
} 

public class PersonServiceFactory : Entities.EntityServiceFactory<PersonService, PersonDao, PersonDaoFactory> 
{ 
} 

所以它的工作了,但怪事是:

  1. 您可以實例化一個工廠,這是必需的(?據我知道做到這一點的唯一方法)爲EntityServiceFactory,但對於有人使用我的API沒有理由讓他們做,但他們仍然可以。

  2. 具有依賴性需求的服務和DAO現在可以實例化爲不帶參數,這會破壞實例化的類方法(但我必須這樣做才能將其用作類型參數)。他們甚至不應該通過實例化這些對象,但他們現在可以並且不正確地這樣做。

我剛剛想到的最後一個問題是,這個解決方案並沒有很好地處理可變數量的依賴關係。仍然想知道是否有更好的方法呢?

結論:我認爲最後,即使它工作,我放棄了很多命令,讓那個通用工廠,這不靈活,並沒有給我太多,所以我可能不會使用在這種情況下,由於限制。

+1

看起來像你所有的問題是因爲你已經標記爲靜態的工廠,而且沒有任何意義,而且考慮到你將使用DI來減少這種靜態依賴 – sll

+2

這些與單身人士有着驚人的相似之處。 –

+1

如果您只需要構建某件東西,則無需構建工廠。 –

回答

2

首先,你是不是使用依賴注入。 Depencency injection與爲泛型類/方法提供類型參數無關。

由於您違反了C#的規則,因此發生錯誤。你必須改變你的代碼以符合它們。所以,讓你的類非靜態的,不要使用私有的構造函數。您可以用一個單例實例替換一個靜態類,並使用受保護的構造函數來避免無控制器實例化。

+0

是的,我正在使用依賴注入,ServiceFactory在Service類的新實例中注入相應的Dao類,並且這很重要,因爲我不能使用Service類作爲泛型類型參數,除非它具有公共空contstructor,它我現在已經嘗試過,並且能夠解決我的一些問題,但現在使用我的API的人可以直接實例化一個服務(他們甚至不應該這樣做),而不使用dao構造函數,這會破壞。你可能在最後一句話中提到過這個問題,但我不確定你的意思,你能舉個例子嗎? – SventoryMang

+0

我編輯了我的帖子,通過刪除所有靜態和私有構造函數,我能夠完成它的工作,但是在編輯中我注意到了一些古怪的東西。 – SventoryMang

+0

標記這是一個答案,因爲它解決了我的第一個問題,但它放棄了太多的值得使用它。 – SventoryMang

0

我知道這個問題真的很老,但我偶然發現了,所以我想我會給出答案。

下編譯並執行你在找什麼做的事:

public abstract class Entity<serviceFactory, serviceClass, daoFactory, daoClass> 
    where daoFactory : Entity<serviceFactory, serviceClass, daoFactory, daoClass>.DaoFactory, new() 
    where daoClass : class, new() 
    where serviceFactory : Entity<serviceFactory, serviceClass, daoFactory, daoClass>.ServiceFactory, new() 
    where serviceClass : class, new() 
{ 
    public abstract class DaoFactory 
    { 
     private static daoClass factorySupportClass; 

     internal static daoClass GetInstance() 
     { 
      if (factorySupportClass == null) 
      { 
       factorySupportClass = new daoFactory().createDao(); 

      } 

      return factorySupportClass; 
     } 

     protected abstract daoClass createDao(); 
    } 

    public abstract class ServiceFactory 
    { 
     private static serviceClass factorySupportClass; 

     internal static serviceClass GetInstance() 
     { 
      if (factorySupportClass == null) 
      { 
       daoClass daoSupportClass = DaoFactory.GetInstance(); 
       factorySupportClass = new serviceFactory().createService(daoSupportClass); 

      } 

      return factorySupportClass; 
     } 
     protected abstract serviceClass createService(daoClass dao); 
    } 
} 

現在,除非你在使用這些類型從組成根內的規劃,我強烈反對這樣做上述解決方案,因爲你的一些依賴關係是隱藏的,更糟糕​​的是,它們固定在一組有限的參數上。相反,請嘗試諸如this之類的更多DI /組合根友善解決方案。