todo依赖注入的时间和地点。你能澄清一下吗?

时间:2012-01-02 10:20:07

标签: c# dependency-injection inversion-of-control

越来越熟悉DI,但我仍然没有多少琐事。

阅读一些文章,其中写着“注射必须在入口点进行”

假设我的情况是我们有wcf服务,内部win / web应用程序使用这些服务,外部第三方使用这些服务。

现在您在哪里注入服务和存储库? 对我来说似乎是一种常见的场景!

我也传递了所有这些接口。(非常适合模拟)如何阻止某人从应该 NOT 调用存储库的层调用EG我的存储库。

EG只有业务层应该调用DAL。 现在,通过向控制器注入一个IRepository,没有什么能阻止开发人员调用DAL。

有什么建议吗?清除所有这些的链接

Noddy我的穷人DI的例子。如何使用unity并在entryPoint注入所有内容?

[TestFixture]
public class Class1
{
    [Test]
    public void GetAll_when_called_is_invoked()
    {
        var mockRepository = new Mock<ICustomerRepository>();
        mockRepository.Setup(x => x.GetAll()).Verifiable();

        new CustomerService(mockRepository.Object);
        ICustomerBiz customerBiz = new CustomerBizImp(mockRepository.Object);

        customerBiz.GetAll();
        mockRepository.Verify(x=>x.GetAll(),Times.AtLeastOnce());
    }
}
public class CustomerService : ICustomerService  //For brevity (in real will be a wcf service)
{
    private readonly ICustomerRepository _customerRepository;

    public CustomerService(ICustomerRepository customerRepository)
    {
        _customerRepository = customerRepository;
    }

    public IEnumerable<Customer> GetAll()
    {
        return _customerRepository.GetAll();
    }
}

public class CustomerBizImp : ICustomerBiz
{
    private readonly ICustomerRepository _customerRepository;

    public CustomerBizImp(ICustomerRepository customerRepository)
    {
        _customerRepository = customerRepository;
    }

    public IEnumerable<Customer> GetAll()
    {
        return _customerRepository.GetAll();
    }
}

public class CustomerRepository : ICustomerRepository
{
    public IEnumerable<Customer> GetAll()
    {
        throw new NotImplementedException();
    }
}
public interface ICustomerRepository
{
    IEnumerable<Customer> GetAll();
}

public interface ICustomerService
{
    IEnumerable<Customer> GetAll();
}

public interface ICustomerBiz
{
    IEnumerable<Customer> GetAll();
}

public class Customer
{
    public int Id { get; set; }
    public string Name { get; set; }
}

感谢

2 个答案:

答案 0 :(得分:5)

这是Composition roots上的博文或您称之为入口点的博文。它来自Dependency Injection in .NET的作者Mark Seemann。如果您正在寻找对DI的深刻理解,那么这本书是必读的。

关于如何组合WCF和DI,有很多样本。如果您在IIS中托管服务,则需要编写自定义 ServiceHostFactory ,以便初始化DI容器。这是Microsoft's Unity的示例。

至于

  

如何阻止某人从不应该调用存储库的层调用EG我的存储库

你是否使用穷人的DI并通过所有层传递所有参考文献?那么你一定要考虑使用DI / IoC容器,如 StructureMap Castle Windsor AutoFac Unity 。< / p>

如果你问“我怎样才能避免出现某人不遵守我的图层边界的情况”:如果程序集引用另一个不应引用的程序(例如UI不应引用DAL),则编写失败的测试。 / p>


<强>更新

我假设您希望该服务使用 ICustomerBiz 而不是 ICustomerRepository 。如果这是正确的, Unity 的设置将如下所示:

[TestMethod]
public void GetAll_with_Unity()
{
  var container = new UnityContainer();
  container.RegisterType<ICustomerRepository, CustomerRepository>();
  container.RegisterType<ICustomerBiz, CustomerBizImp>();
  container.RegisterType<ICustomerService, CustomerService>();
  var svc = container.Resolve<ICustomerService>();
  var all = svc.GetAll();
  Assert.AreEqual(1, all.Count());
}

答案 1 :(得分:0)

DI更多的是在依赖体系结构中注入依赖关系,这就是为什么它无法解决你面临的层隔离问题。

如果需要,生产代码可以和 包含DI代码。

  • 如果我们在讨论plugin-based架构DI是最自然的选择之一。

  • 如果我们正在谈论应用程序行为更改,例如Logging系统选择:如果连接存在,则保存在远程服务器上,如果不是因为本地记录器未来与服务器同步,则保存。

    < / LI>

生产中有DI的大量用法,但 >如果使用它。

换句话说,它没有单一的使用规则,对于任何钉子都不是悍马,所以在认为它是合适的并且明智地使用它的地方使用它。