Общая жизненная конфигурация репозитория с Windsor - PullRequest
2 голосов
/ 20 апреля 2011

У меня нет идей, как настроить правильный контейнер Windsor для использования с репозиториями в приложении Windows.У меня есть общая реализация репозитория Repository, где T является типом сущности, у него есть зависимость IDatacontextProvider, которая предоставляет для него datacontext:

public class Repository<T> : IRepository<T> where T : class
{
    protected DataContext DataContext;
    public Repository(IDataContextProvider dataContextProvider) {
         DataContext = dataContextProvider.DataContext;
    }
    ....
}

И для простых вещей все работает нормально со следующей конфигурацией:

 container.Register(                                
            Component.For<IDataContextProvider>()
                  .ImplementedBy<DataContextProvider>()
                  .Lifestyle.Transient,
            Component.For(typeof(IRepository<>))
                  .ImplementedBy(typeof(Repository<>))
                  .Lifestyle.Transient, .... 

Проблемы возникают, когда я пытаюсь объединить разные объекты из нескольких репозиториев, если каждый экземпляр репозитория имеет свой экземпляр контекста данных.
Например, у меня есть простой сервис:

public class SimpleService : ISimpleService {
     public SimpleService(IRepository<Order>, IRepository<OrderLine>) {
         ....
     }
}

Iмог бы сделать IDataContextProvider в качестве Singleton, но я думаю, что это принесло бы еще большие проблемы.
Я мог бы передать IDataContextProvider в SimpleService и попытаться разрешить там экземпляры репозитория, но для этого потребовался бы дополнительный код, чтобы сделать сервис легко тестируемым, и потребовались бы дополнительные зависимости,Может быть, у кого-то есть лучшая идея, как решить эту проблему?

обновление: следуя совету, я создал фабрику хранилища (она немного отличается от предложенной в ответе, у нее нет прямой зависимости от datacontext, но идеяочень то же самое):

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

public class RepositoryFactory : IRepositoryFactory
{
    private readonly IDataContextProvider dataContextProvider;

    public RepositoryFactory(IDataContextProvider dataContextProvider)
    {
        this.dataContextProvider = dataContextProvider;
    }

    public IRepository<T> GetRepository<T>() where T : class
    {
        return new Repository<T>(dataContextProvider);
    }
}

Ответы [ 3 ]

2 голосов
/ 20 апреля 2011

Как насчет наличия другого промежуточного слоя, такого как RepositoryFactory? Это может иметь переходный образ жизни. Все репозитории, созданные на фабрике, будут использовать один и тот же экземпляр DataContext. Вам также необходимо изменить классы репозитория, чтобы они использовали экземпляр DataContext вместо DataContextProvider.

public class RepositoryFactory : IRepositoryFactory
{
   protected DataContext dataContext;
   public RepositoryFactory(IDataContextProvider provider)
   {
      dataContext = dataContextProvider.DataContext;
   }

   public IRepository<T> GetRepository<T>()
   {
      return new Repository<T>(dataContext);
   }
}

public class SimpleService : ISimpleService {
     public SimpleService(IRepositoryFactory factory) {
         ....
     }
}
1 голос
/ 20 апреля 2011

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

  1. Я не знаю подробностей вашего приложения, но, возможно, вы можете написать свой собственный менеджер образа жизни для IDatacontextProvider (поскольку вы говорите, что ни синглтон, ни переходный процесс вам не подходит).
  2. Если вы хотите убедиться, что один и тот же IDatacontextProvider передан между репозиториями, возможно, вам следует подумать о , предоставив его явно в качестве параметра метода вместо внедренной зависимости.
  3. @ Ответ Can также является возможным решением, я сам его использовал один раз.
0 голосов
/ 16 июля 2011

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

В моем блоге вы можете найти простой пример http://marcofranssen.nl внедрения зависимостей в сочетании с mvc3 и EF Code.

...