В качестве альтернативы вашему собственному решению, вы можете попытаться определить фабрику для создания новых экземпляров репозитория:
public interface IRepositoryFactory
{
IRepository<TEntity, TPrimaryKey>
CreateRepository<TEntity, TPrimaryKey>();
// Perhaps other overloads here
}
internal class RepositoryFactory : IRepositoryFactory
{
public IContainer Container { get; set; }
public IRepository<TEntity, TPrimaryKey>
CreateRepository<TEntity, TPrimaryKey>()
{
return container.Resolve<Repository<TEntity, TPrimaryKey>>();
}
}
Вы можете зарегистрировать RepositoryFactory
следующим образом:
builder.Register(c => new RepositoryFactory() { Container = c })
.As<IRepositoryFactory>()
.SingleInstance();
Теперь вы можете объявить IRepositoryFactory
в качестве аргумента конструктора и создать новые экземпляры.Посмотрите, например, на этот класс ProcessUserAccountUpgradeCommand
, который использует внедрение зависимостей для своих зависимостей:
public ProcessUserAccountUpgradeCommand : ServiceCommand
{
private readonly IRepositoryFactory factory;
ProcessUserAccountUpgradeCommand(IRepositoryFactory factory)
{
this.factory = factory;
}
protected override void ExecuteInternal()
{
// Just call the factory to get a repository.
var repository = this.factory.CreateRepository<User, int>();
User user = repository.GetByKey(5);
}
}
Хотя использование фабрики может показаться немного громоздким, а не получение хранилища напрямую, ваш проект будет четко сообщать, чтовосстанавливается новый экземпляр (потому что вы вызываете метод CreateRepository
).Экземпляры, возвращаемые из контейнера IoC, обычно , как ожидается, будут иметь длительный срок службы .
Еще один совет: вы можете захотеть рефакторизовать использование типа первичного ключа.Было бы затруднительно всегда запрашивать репозитории <User, int>
вместо просто <User>
репозиториев.Возможно, вы найдете способ абстрагировать первичный ключ от фабрики.
Надеюсь, это поможет.