Gus*_*tav 5 .net dependency-injection castle-windsor ioc-container
我有这些接口:
public interface IUnitOfWork
{
IPersonRepository People { get; }
IBookRepository Books { get; }
int Commit();
}
public interface IBookRepository
{
Book GetBookById(int id);
IQueryable<Book> GetAllBooks();
}
public interface IPersonRepository
{
Person GetPersonById(int id);
IQueryable<Person> GetAllPeople();
}
Run Code Online (Sandbox Code Playgroud)
我实现IUnitOfWork如下:
public class SqlUnitOfWork : IUnitOfWork
{
private readonly DbContext dbContext;
public SqlUnitOfWork()
{
dbContext = new DbContext("name=SQLContainer");
}
public IPersonRepository People
{
get { return IoC.Container.Resolve<IPersonRepository>(new { DbContext = dbContext }); }
}
public IBookRepository Books
{
get { return IoC.Container.Resolve<IBookRepository>(new { DbContext = dbContext }); }
}
public int Commit()
{
return dbContext.SaveChanges();
}
}
Run Code Online (Sandbox Code Playgroud)
实现IBookRepository和IPersonRepository使用构造函数,该构造函数将a DbContext作为参数,并且此DbContext是在SqlUnitOfWork(上面的代码)中创建的,并且我使用Resolve方法的重载传递此参数.
我的问题是,这是正确的方法吗?这是一个好习惯吗?
谢谢!
使用DI容器作为服务定位器几乎不是一个好习惯.除此之外,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();
}
}
Run Code Online (Sandbox Code Playgroud)
即使没有明确的共享DbContext,也可以通过容器进行配置.由于这个问题的背景表明,温莎城堡是正在使用的容器,默认的寿命已经是单身,所以你不要有明确此设置.使用Castle Windsor,DbContext将在SqlUnitOfWork类和两个存储库之间自动共享.
但是,您还可以显式配置要共享的上下文,如下所示:
container.Register(Component.For<DbContext>().LifeStyle.Singleton);
Run Code Online (Sandbox Code Playgroud)
如果您要使用另一个DI容器,API会有所不同,但概念是相同的.
额外信息:我不知道整体上下文是什么,但是如果要在Web应用程序中使用它并且DbContext是实体框架或LINQ to SQL上下文,那么正确的生命周期配置将是PerWebRequest,而不是那些上下文类是线程安全的:
container.Register(Component.For<DbContext>().LifeStyle.PerWebRequest);
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2005 次 |
| 最近记录: |