Проект с несколькими экземплярами ObjectContext
допустим только в том случае, если ваши Repository
методы фиксируют транзакцию. В противном случае, возможно, что внешние вызовы для фиксации транзакции не сохранят все, что вы намереваетесь, потому что вы будете хранить ссылки на различные экземпляры ObjectContext
.
Если вы хотите ограничить ObjectContext
одним экземпляром, то вы можете создать класс RepositoryProvider
, который содержит ObjectContext
и управляет распространением действий репозитория на фиксации данных. Это может быть лучше всего достигнуто любым,
- вставка ссылки ObjectContext
в каждый репозиторий или
- Подписка событий репозиториев на EventHandler
s, которые вызывают соответствующие методы на ObjectContext
.
Ниже приведена очень плагинная реализация, которую я использовал:
Интерфейс провайдера репозитория
public interface IRepositoryProvider
{
IRepository this[Type repositoryType] { get; }
}
Интерфейс хранилища фабрики
Реализация зависит от IEnumerable<IFilteredRepositoryFactory>
.
public interface IFilteredRepositoryFactory{
bool CanCreateRepository(Type repositoryType);
IRepository CreateRepository(Type repositoryType, ObjectContext context);
}
Итак, реализация выглядит так:
Класс поставщика репозитория
public class RepositoryProvider
{
public RepositoryProvider(ObjectContext context, IEnumerable<IFilteredRepositoryFactory> repositoryFactories)
{
_context = context;
_repositoryFactories = repositoryFactories;
}
private readonly ObjectContext _context;
private readonly IEnumerable<IFilteredRepositoryFactory> _repositoryFactories;
private readonly Dictionary<Type, IRepository> _loadedRepositories;
IRepository this[Type repositoryType]
{
get
{
if(_loadedRepositories.ContainsKey(repositoryType))
{
return _loadedRepositories[repositoryType];
}
var repository = GetFactory(repositoryType).CreateRepository(repositoryType, _context);
_loadedRepositories.Add(repositoryType,repository);
return repository;
}
}
IFilteredRepositoryFactory GetFactory(Type repositoryType)
{
//throws an exception if no repository factory is found
return _repositoryFactories.First(x => x.CanCreateRepository(repositoryType));
}
}
Следует отметить, что новая Repository
будет создана первой соответствующей фабричной реализацией. Таким образом, если коллекция фабрик содержит несколько фабрик, которые могут создать Repository
для данного репозитория Type
, будет использован первый объект IFilteredRepositoryFactory
в перечисляемом объекте, а любые последующие фабрики будут игнорироваться , Кроме того, если зарегистрированной фабрики нет, будет выдано исключение.