.net 帮助了解Windsor、存储库和工作单元模式

.net 帮助了解Windsor、存储库和工作单元模式,.net,dependency-injection,castle-windsor,ioc-container,.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

我有以下接口:

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();
}
IBookRepository
IPersonRepository
的实现使用一个构造函数,该构造函数将
DbContext
作为参数,该DbContext在SqlUnitOfWork(上面的代码)中创建,我使用Resolve方法的重载传递该参数

我的问题是,这样做对吗?这是一种好的做法吗

谢谢

使用DI容器作为。除此之外,在解析接口时将
DbContext
传递给容器是一个泄漏的抽象,因为这意味着您了解一些不应该了解的具体实现

相反,我建议构造函数注入,它应该是这样的:

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();
    }
}
container.Register(Component.For<DbContext>().LifeStyle.Singleton);
即使没有显式共享
DbContext
,也可以通过容器进行配置。因为这个问题的上下文表明Castle Windsor是正在使用的容器,所以默认生存期已经是Singleton,所以您不必显式地设置它。在Castle Windsor中,
DbContext
将自动在
SqlUnitOfWork
类和两个存储库之间共享

但是,您也可以显式配置要共享的上下文,如下所示:

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();
    }
}
container.Register(Component.For<DbContext>().LifeStyle.Singleton);

看一看。它显示了类似的方法。它可能会给你一些想法。构造函数注入不是有点不理想;web请求可能只需要
SqlUnitOfWork.People.Get(322)但是bookRepository的实例也被创建了(因为它在构造函数中),即使它不是必需的