Как использовать IoC DI с этим шаблоном репозитория?
Я использую шаблон репозитория, найденный в ответе на этот вопрос SO:
Преимущество создания общего репозитория против конкретного репозитория для каждого объекта?
А именно, каждый репозиторий наследуется от абстрактного базового класса, который содержит общие методы, такие как добавление, удаление и т.д., а также реализует определенный интерфейс репозитория для любых методов, которые являются уникальными для этого репозитория/сущности.
т.
public class CompanyRepository : Repository<Company>, ICompanyRepository {
...
}
В моем бизнес-уровне я использую Structure Map, чтобы получить экземпляр репозитория, но я не уверен, как его использовать.
// Structure Map initialisation
ObjectFactory.Initialize(
x =>
{
x.For<ICompanyRepository>().Use<CompanyRepository>();
});
разрешение экземпляра:
return ObjectFactory.GetInstance<ICompanyRepository>();
Однако экземпляр, который я получаю, представляет собой интерфейс, а не всю реализацию репозитория. У меня нет доступа к методам базового класса (Repository<Company>
). Каков обычный способ сделать это?
Ответы
Ответ 1
Ключевым моментом здесь является думать о Repository<>
исключительно как деталь реализации. Вы не будете получать доступ к каким-либо методам непосредственно; вместо этого вы откроете все методы, включая Insert
и Delete
, на интерфейсе:
public interface ICustomerRepository
{
// ...Customer-specific queries...
void Insert(Customer customer);
void Delete(Customer customer);
}
Когда вы реализуете интерфейс в CustomerRepository
, вам просто нужно передать вызовы Insert
и Delete
через защищенные методы Repository<>
, как описано в исходном вопросе.
Регистрация StructureMap, указанная в вопросе, является именно тем, чего я ожидал бы. Цель Repository<>
заключается в том, чтобы помочь в реализации интерфейсов, специфичных для сущности. Имейте в виду, что интерфейсы всегда будут содержать полный публичный API хранилища и который должен указывать на вас в правильном направлении.
Ответ 2
Почему бы не
return ObjectFactory.GetInstance<Repository<Company>>;
? Вам необходимо будет соответствующим образом изменить вашу инициализацию ObjectFactory:
// Structure Map initialisation
ObjectFactory.Initialize(
x => {
x.For<Repository<Company>>().Use<CompanyRepository>();
});
ИЗМЕНИТЬ
Если вы все еще хотите получить Repository<Company>
также для ICompanyRepository
, вам нужно объявить переадресацию:
// Structure Map initialisation
ObjectFactory.Initialize(
x => {
x.For<Repository<Company>>().Use<CompanyRepository>();
x.Forward<Repository<Company>, ICompanyRepository>();
});