如何避免在DL-BL-UI图层之间进行投射? (C#)

时间:2011-06-19 07:25:35

标签: casting business-logic facade

我设计的应用程序基本上有3个不同的逻辑层:

  1. DB连接器(由ADO.NET实现)。
  2. BL业务逻辑(UI唯一知道的东西)。
  3. 数据库存储库(连接前两个)。
  4. 数据库存储库分为依赖关系部分,每个最终实体都是一个接口的多态。在某些情况下,相同依赖关系部分内的对象之间存在依赖关系 - 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); 
        }
    }
    

1 个答案:

答案 0 :(得分:0)

有点难以分辨这里发生了什么,但我认为关键是要利用这样的仿制药:

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

如果我理解你的问题,这将允许你说:

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

您需要更改代码中的几乎每个类才能使用泛型。