0

基本的に3つの異なるロジックレイヤーを持つアプリケーションを設計しています:

  1. DB コネクタ (ADO.NET によって実装)。
  2. BL ビジネス ロジック (UI が知っている唯一のこと)。
  3. DB リポジトリ (最初の 2 つを接続します)。

DB リポジトリは依存関係のセクションに分割され、すべての最終的なエンティティは 1 つのインターフェイスにポリモーフィックです。場合によっては、同じ依存関係セクション - ISectionFactory (したがって依存) 内のオブジェクト間に依存関係があります。実際には、BL は MainFactory から特定の型 (私の例では IngrediantType など) のオブジェクトを要求します (これはすべての DB の要因です)。この設計のために、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); 
    }
}
4

1 に答える 1

0

ここで何が起こっているのかを伝えるのは少し難しいですが、鍵は次のようなジェネリックを利用することだと思います:

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

あなたの質問を正しく理解できれば、次のように言えます。

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

ジェネリックを使用するには、コード内のほぼすべてのクラスを変更する必要があります。

于 2011-06-19T07:50:29.600 に答える