Разделение репозитория Dal с помощью шаблона Factory

Я пытаюсь отделить Bll от Dal, используя некоторые интерфейсы и шаблон Factory. Data.Contracts, содержащие интерфейсы, будут указаны в моем Bll.

Это небольшой тестовый код:

class Program
{
    static void Main(string[] args)
    {
        IDataRepositoryFactory _DataRepositoryFactory;
        IUserRepository userRepository = _DataRepositoryFactory.GetDataRepository<IUserRepository>();
     }
}


public abstract class RepositoryBase<T> where T : class, new() { }
public class UserRepository : RepositoryBase<User>, IUserRepository 
{
    public UserRepository() { }
}

public class DataRepositoryFactory : IDataRepositoryFactory
{
    public T GetDataRepository<T>() where T : IDataRepository, new()
    {
        return ObjectBase.Container.GetExportedValue<T>();
    }
}

public class User 
{
    public int Id { get; set; }
}

public abstract class ObjectBase
{
    public ObjectBase() { }

    public static CompositionContainer Container { get; set; }

}

public interface IDataRepository { }

public interface IDataRepository<T> : IDataRepository where T : class, new() { }

public interface IUserRepository : IDataRepository { }

public interface IDataRepositoryFactory
{
    T GetDataRepository<T>() where T : IDataRepository, new();
}

Наконец я получил свою ошибку:

«Data.Contracts.IUserRepository» должен быть неабстрактным типом с общедоступным конструктором без параметров, чтобы использовать его в качестве параметра «T» в универсальном типе или методе «Data.Contracts.IDataRepositoryFactory.GetDataRepository()»

Мой вопрос: какова правильная реализация для разделения кода на бизнес-уровне с использованием фабричного шаблона? Я не могу использовать конкретную реализацию UserRepository, поскольку она наследуется от классов, которые мне не нужны в BLL.

Любая помощь будет оценена по достоинству.


person MyOwnWay    schedule 07.12.2013    source источник


Ответы (1)


С точки зрения кода вы должны просто отключить «новое» ограничение на заводском интерфейсе:

public interface IDataRepositoryFactory
{
    T GetDataRepository<T>() where T : IDataRepository; //, new();
}

public class DataRepositoryFactory : IDataRepositoryFactory
{
    public T GetDataRepository<T>() where T : IDataRepository//, new()
    {
        return ObjectBase.Container.GetExportedValue<T>();
    }
}

С точки зрения дизайна репозитории выглядят немного сложно:

Для меня IDataRepository (неуниверсальный) и RepositoryBase кажутся избыточными, но это зависит от конкретного случая (возможно, вы не предоставили достаточно подробностей). Я бы использовал цепочку наследования IDataRepository<T> -> IUserRepository:IDataRepository<User> -> UserRepository.

Также не ясно, какие типы относятся к BLL.

Например, эта разбивка выглядит нормально для меня:

  • BLL:
    • User
    • IUserRepository:IDataRepository<User>
  • DAL/Infrastructure:
    • IDataRepositoryFactory
    • IDataRepositoryFactory:IDataRepositoryFactory
    • IDataRepository<T>
    • UserRepository

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

person mikalai    schedule 10.12.2013
comment
Спасибо, я нашел в своей реализации одно ограничение, которое не работало, я пересобрал небольшое консольное приложение с более простой моделью и DI и решил. - person MyOwnWay; 11.12.2013