Как реализовать универсальный RepositoryFactory? - PullRequest
8 голосов
/ 21 декабря 2010

Я пытаюсь реализовать универсальный репозиторий.Это то, что у меня так далеко ...

public interface IRepositoryFactory
{
    IRepository<T> RepositoryOf<T>() where T : class;
}

public class EntityFrameworkRepositoryFactory : IRepositoryFactory
{
    private readonly IWindsorContainer _container;

    public EntityFrameworkRepositoryFactory(IWindsorContainer container)
    {
        _container = container;
    }

    public IRepository<T> RepositoryOf<T>() where T : class
    {
        var repository = _container.Resolve<IRepository<T>>();
        return repository;
    }
}

RepositoryFactory используется моей единицей реализации работы

public interface IUnitOfWork : IDisposable
{
    IRepository<T> RepositoryOf<T>() where T : class;
    void Commit();
}

В любом случае, я хочу задать вопрос:если реализация RepositoryFactory зависит от IWindsorContainer - это правильно?

Мне нужен был способ запроса IRepository любого типа, поэтому мой код установщика делает это ...

// Windsor Container
container.Register(
    Component.For<IWindsorContainer>()
        .Named("Container")
        .Instance(container)
    );

Что только кажетсяидти против всей концепции IoC, но тогда, может быть, вся идея запроса о хранилище делает это в любом случае.

Редактировать (Как ответ на miensol ответ)

Я уже использую Windsor для создания репозиториев для меня со следующим кодом в моем установщике ...

// Generic Repository
container.Register(
    Component.For(typeof (IRepository<>))
        .ImplementedBy(typeof (EntityFrameworkRepository<>))
        .ServiceOverrides(
            ServiceOverride.ForKey("objectContext").Eq("ObjectContext"))
    );

В прошлом я использовал ServiceLocator для достижения того, чего я хочу, но прочитал, что это немного против паттерна.Поэтому пытался избежать его использования.Хотя я должен признать, что я не уверен, почему, поскольку то, что я сделал, также кажется неправильным, так как я обязан использовать Castle Windsor в качестве моей платформы IoC / DI.Сервисный локатор должен быть независимым от фреймворка.

Итак, я немного запутался!

1 Ответ

5 голосов
/ 21 декабря 2010

Я не совсем уверен, зачем вам нужен IRepositoryFactory, когда вы используете IoC Framework.Однако наличие зависимостей от конкретных реализаций контейнера IoC разбросано, хотя основа кода, как правило, не очень хорошая идея.В большинстве случаев, когда я действительно не могу найти способ заставить контейнер вводить зависимости в мои объекты, я использую шаблон локатора служб, здесь , для которого вы можете найти часто используемую реализацию.сеть.Тогда ваш фабричный метод будет выглядеть так:

public IRepository<T> RepositoryOf<T>() where T : class
{
  return ServiceLocator.Current.GetInstance<IRepository<T>>();
}

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

container.Register(
  Component.For(typeof(IRepository<>)).ImplementedBy(typeof(GenericRepositoryImplementation<>))
);

и сделать так, чтобы они были введеныобъекты вроде так:

public class ClassThatRequiresSomeRepos
{
  IRepository<OneEntity> repoOne;
  IRepository<TwoEntity> repoTwo;

  public ClassThatRequiresSomeRepos(IRepository<OneEntity> oneEntityRepository, IRepository<TwoEntity> twoEntityRepository)
  {
    _repoOne = oneEntityRepository;
    _repoTwo = twoEntityRepository;
  }
} 
...