Как избежать приведения между слоями DL - BL - UI? (С #) - PullRequest
0 голосов
/ 19 июня 2011

Я разрабатываю приложения, которые в основном имеют 3 различных логических уровня:

  1. Соединитель БД (реализован ADO.NET).
  2. BL - бизнес-логика (единственный интерфейс)знает).
  3. Репозитории БД (соединяются между первыми двумя).

Репозитории БД разделены на секции зависимости, и каждый конечный объект полиморфен одному интерфейсу.В некоторых случаях существуют зависимости между объектами внутри одного и того же раздела зависимостей - ISectionFactory (следовательно, зависимый).На практике BL собирается запросить объект определенного типа (например, IngrediantType в моем примере) из MainFactory (который является фактором для всей БД). Из-за этого дизайна я вынужден приводить типы в пользовательском интерфейсе, которыйочевидно, это сопротивление.Как я могу изменить дизайн?Вот краткий взгляд на дизайн:

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 голосов
/ 19 июня 2011

Немного сложно сказать, что здесь происходит, но я думаю, что ключ будет в том, чтобы воспользоваться преимуществами дженериков следующим образом:

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

Если я правильно понимаю ваш вопрос, это позволит вамскажем:

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

Вам потребуется изменить почти каждый класс в вашем коде, чтобы использовать дженерики.

...