Как использовать 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>();
    });