Использование DI-контейнера в качестве Service Locator вряд ли можно назвать хорошей практикой . В дополнение к этому, передача DbContext
в контейнер при разрешении интерфейса является Leaky Abstraction , потому что это подразумевает, что вы знаете что-то о конкретной реализации, чего не должны делать.
Вместо этого я бы порекомендовал Конструктор Инъекций , который будет выглядеть примерно так:
public class SqlUnitOfWork : IUnitOfWork
{
private readonly DbContext dbContext;
private readonly IPersonRepository personRepository;
private readonly IBookRepository bookRepository;
public SqlUnitOfWork(DbContext dbContext,
IPersonRepository personRepository, IBookRepository bookRepository)
{
if (dbContext == null)
throw new ArgumentNullException("dbContext");
if (personRepository == null)
throw new ArgumentNullException("personRepository");
if (bookRepository = null)
throw new ArgumentNullException("bookRepository");
this.dbContext = dbContext;
this.personRepository = personRepository;
this.bookRepository = bookRepository;
}
public IPersonRepository People
{
get { return this.personRepository; }
}
public IBookRepository Books
{
get { return this.bookRepository; }
}
public int Commit()
{
return this.dbContext.SaveChanges();
}
}
Несмотря на то, что нет явного совместного использования DbContext
, это можно настроить через контейнер. Поскольку контекст этого вопроса указывает на то, что Castle Windsor является используемым контейнером, время жизни по умолчанию уже Singleton, поэтому у вас нет , чтобы явно настроить это. С Castle Windsor DbContext
будет автоматически разделен между классом SqlUnitOfWork
и обоими репозиториями.
Однако вы также можете явно настроить контекст для совместного использования, например:
container.Register(Component.For<DbContext>().LifeStyle.Singleton);
Если бы вы использовали другой DI-контейнер, API был бы другим, но концепция та же.
Информация о бонусе: я не знаю, каков общий контекст, но , если , это должно использоваться в веб-приложении, а DbContext
- это Entity Framework или контекст LINQ to SQL, правильный конфигурация времени жизни вместо этого будет PerWebRequest, поскольку ни один из этих классов контекста не является поточно-ориентированным:
container.Register(Component.For<DbContext>().LifeStyle.PerWebRequest);