2011-06-19 53 views
0

我設計基本上有3個不同的邏輯層的應用:如何避免在DL - BL - UI圖層之間進行投射? (C#)

  1. DB連接器(由ADO.NET實現)。
  2. BL業務邏輯(UI知道的唯一事物)。
  3. 數據庫存儲庫(連接前兩個數據庫)。

數據庫存儲庫被分成多個依賴部分,每個最終實體都是多態的一個接口。在某些情況下,在相同的依賴關係部分內的對象之間存在依賴關係 - ISectionFactory(因此依賴)。 實際上,BL將從MainFactory中請求一個特定類型的對象(如我的示例中的IngrediantType)(這是所有數據庫的一個因子) 由於此設計,我被迫在UI上投入類型 - 這顯然是一個阻力。 如何更改設計? 下面是設計的一個簡單的介紹一下:

public class MainFactory 
{ 
    private Dictionary<Type, ISectionFactory> m_SectionsFactories; 
    private ISectionFactory treatmentsSectionFactory = 
      new TreatmentsSectionFactory(); 

    public MainFactory() 
    { 
     m_SectionsFactories = new Dictionary<Type, ISectionFactory> 
      { 
       {typeof(IngrediantType),treatmentsSectionFactory} 
      }; 
    } 

    public IConcreteDataCollection GetConcreteData(Type i_EntitiesName) 
    { 
     return m_SectionsFactories[i_EntitiesName] 
      .GetConcreteData(i_EntitiesName); 
    } 
} 

internal interface ISectionFactory 
{ 
    IConcreteDataCollection GetConcreteData(Type i_EntitiesName); 
} 

public class TreatmentsSectionFactory : ISectionFactory 
{ 
    private Dictionary<Type, IConcreteDataCollection> 
      m_ConcreteDataCollections; 

    private IngrediantTypes m_IngrediantTypes = new IngrediantTypes(); 
    private Ingrediants m_Ingrediants = new Ingrediants(); 

    public TreatmentsSectionFactory() 
    { 
     m_ConcreteDataCollections = 
      new Dictionary<Type, IConcreteDataCollection>(); 
     m_ConcreteDataCollections 
      .Add(typeof(IngrediantType), m_IngrediantTypes); 
     m_ConcreteDataCollections 
      .Add(typeof(Ingrediants), m_Ingrediants); 
    } 

    public IConcreteDataCollection GetConcreteData(Type i_EntitiesName) 
    { 
     return m_ConcreteDataCollections[i_EntitiesName]; 
    } 
} 

public interface IConcreteDataCollection : IEnumerable 
{ 
    // Iteratable. 
    IConcreteData GetById(int i_Id); 
    void AddNewConcreteData(IConcreteData i_ConcreteData); 
    void UppdateConcreteData(IConcreteData i_ConcreteData); 
    void DeleteConcreteData(IConcreteData i_ConcreteToDelete); 
} 

public class IngrediantTypes : IConcreteDataCollection 
{ 
    public string TestType { get; set; } 
    public IConcreteData GetById(int i_Id){} 
    public void AddNewConcreteData(IConcreteData i_ConcreteData){} 
    public void UppdateConcreteData(IConcreteData i_ConcreteData){} 
    public void DeleteConcreteData(IConcreteData i_ConcreteToDelete){}   
    public IEnumerator GetEnumerator(){} 
} 

// also implements IConcreteDataCollection 
public class Ingrediants : IConcreteDataCollection 
{ 
} 

public interface IConcreteData 
{ 
    public int Index { set; get; }   
} // the final (highest) entity of all DB entities 

public class IngrediantType : IConcreteData 
{ 
    public int Index { set; get; } 
    // other set of properties 
} 

public class Ingrediant : IConcreteData 
{ 
    public int Index { set; get; } 
    public IngrediantType RelatedIngrediantType { set; get; } 
    // other set of properties 
} 

public class mainClass 
{ 
    public static void main() 
    { 
     MainFactory factory = new MainFactory(); 

     var type = typeof(IngrediantType); 

     // returns a IngrdiantTypes of type (IConcreteDataCollection) 
     var t = factory.GetConcreteData(typeof(IngrediantType)); 

     // I want to use the IngrediantType without casting !!! 
     var s = t.GetById(2); 
    } 
} 

回答

0

這是一個有點很難說這是怎麼回事,但我認爲,關鍵是要充分利用仿製藥的,像這樣:

public IConcreteDataCollection<T> GetConcreteData<T>() 
{ 
    return ...; 
} 

如果我正確地理解你的問題,這將允許你說:

var t = factory.GetConcreteData<IngrediantType>(); 

你需要改變你的代碼中使用仿製藥幾乎每一個類。