BAL中的依赖注入,无需向DAL添加项目引用

时间:2012-09-23 18:50:35

标签: c# entity-framework dependency-injection domain-driven-design ninject

这与发布的问题here有关。我的核心项目有以下内容。

public interface IRepository<T> : IDisposable  
{  
    IQueryable<T> All { get; }  
    IQueryable<T> AllIncluding(params Expression<Func<T, object>>[] includeProperties);  
    TEntity Find(int id);  
    void InsertOrUpdate(T entity);  
    void Delete(int id);  
    void Save();  
}  

public class Customer  
{  
    public int Id { get; set; }  
    public string FirstName { get; set; }  
    public string LastName { get; set; }   
} 

DAL有CustomerContext和CustomerRepository。该项目依赖于实体框架。

public class CustomerContext : DbContext
{
    public DbSet<Customer> Customers { get; set; }
}

public class CustomerRepository : IRepository<Customer>
{

}

接下来是我的BAL。这是一个类库项目。我需要在客户存储库上执行一些操作,但我想这样做而不直接添加对DAL的依赖。我试图通过DI使用ninject做。我正在设置IRepository和CustomerRepository之间的绑定,如下所示。

var Kernel = new StandardKernel();  
Kernel.Bind<IRepository>().To<CustomerRepository>();  
  1. 假设我有一个UI应用程序,它将从BAL调用一些API。应该放置用于将IRepository绑定到CustomerRepository的上述代码吗?有没有办法通过App.config进行这种绑定?

  2. 正如您所看到的,如果我把它放在BAL中,那么我将不得不添加对DAL项目的引用,因为我使用的是在DAL层中定义的CustomerRepository。

2 个答案:

答案 0 :(得分:4)

首先:不要使用公开IQueryable<TEntity>的通用存储库。

  1. 你在编写单元测试时是否尝试过模拟它们?
  2. 他们就是我们所谓的漏洞抽象。
  3. 您的问题:

      

    假设我有一个UI应用程序,它将从BAL调用一些API。应该放置用于将IRepository绑定到CustomerRepository的上述代码吗?有没有办法通过App.config进行这种绑定?

    为什么不能从UI项目中为DAL添加依赖项?它还将简化安装,因为在您发布项目和/或创建安装程序包时将自动包含DAL。

      

    正如您所看到的,如果我将它放在BAL中,那么我将不得不添加对DAL项目的引用,因为我正在使用在DAL层中定义的CustomerRepository。

    不要在BAL中创建引用或配置。这是作为根的UI项目。因此,任何配置都应添加到其中。

    我通常在每个项目中创建一个组合根,然后从我的启动项目中调用每个组件中的根。这意味着启动项目只需要知道我们得到了哪些项目,而不是它们包含的内容。

答案 1 :(得分:3)

您永远不会在低级别图层中设置容器。相反,您在层次结构的某个地方有一个组合根。对于桌面应用程序,Main是一个很好的候选者。在Web应用程序中,它将是Global.asax的{​​{1}}。