越来越熟悉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; }
}
感谢
答案 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
系统选择:如果连接存在,则保存在远程服务器上,如果不是因为本地记录器未来与服务器同步,则保存。
生产中有DI
的大量用法,但 >如果使用它。
换句话说,它没有单一的使用规则,对于任何钉子都不是悍马,所以在你认为它是合适的并且明智地使用它的地方使用它。