如何在多级类层次结构中使用依赖注入? 例如: -
public class ModuleClassViewModel
{
ModulePageClassServiceRepository _modulePageClassServiceRepository = null;
public ModuleClassViewModel(ModulePageClassServiceRepository modulePageClassServiceRepository)
{
_modulePageClassServiceRepository = modulePageClassServiceRepository;
}
public IList<ModulePageClassObject> ModuleClassPageHierarchy(int? modulePageClassID, string SecureKey)
{
return _modulePageClassServiceRepository.ModuleClassPageHierarchy(....);
}
}
和ModulePageClassServiceRepository的代码是.......
public class ModulePageClassServiceRepository : IModulePageClassService
{
ServiceDAO _serviceDAO = null
public ModulePageClassServiceRepository(ServiceDAO serviceDAO )
{
serviceDAO = serviceDAO ;
}
public IList<ModulePageClassObject> ModuleClassPageHierarchy(ModuleClassPageHierarchyParameter moduleClassPageHierarchyParameter)
{
// call serviceDAO and return result
}
}
现在根据DI,如果我们想要使用ModuleClassViewModel,那么我们首先需要注入ModulePageClassServiceRepository对象,对于ModulePageClassServiceRepository我们需要serviceDAO ....这个层次结构可以增长到多个级别.... 在Test class中假设....
public class TestDI
{
public void TestMethod()
{
ServiceDAO objServiceDAO = new ServiceDAO();
ModulePageClassServiceRepository objModulePageClassServiceRepository = new ModulePageClassServiceRepository (objServiceDAO );
ModuleClassViewModel objModuleClassViewModel = new ModuleClassViewModel(objModulePageClassServiceRepository );
//call method of objModuleClassViewModel
}
}
这是使用依赖注入的正确方法吗?在这里我需要首先初始化完整的层次结构,所以我的问题是 - 我是否需要首先初始化这个完整的层次结构....或者有没有其他方法来调用ModuleClassViewModel类???
答案 0 :(得分:1)
此代码按照我的测试工作。
我建议您使用企业库块Unity,以实现它。 要下载它,请点击此处:http://msdn.microsoft.com/en-us/library/dn169621.aspx,或尝试使用NUget获取它:https://www.nuget.org/packages/EnterpriseLibrary.Common/
首先,您需要通过使所有类实现接口来更改您的设计。那将是:
class ClassA : InterfaceA {...}
class ClassB : InterfaceB {...}
class ClassC : InterfaceC {...}
添加对这些程序集的引用:
在您真正的实施中,将其放在&#34; ClassA&#34;呼叫者: (见更多http://msdn.microsoft.com/en-us/library/ff648271.aspx)
using Microsoft.Practices.Unity;
(...)
IUnityContainer myContainer = new UnityContainer();
myContainer.RegisterType<InterfaceA,ClassA>();
myContainer.RegisterType<InterfaceB, ClassB>();
myContainer.RegisterType<InterfaceC, ClassC>();
InterfaceA iA = myContainer.Resolve<InterfaceA>();
在您的测试实现中,使用Moq框架(https://code.google.com/p/moq/),您将能够执行此操作:
Mock<InterfaceB> interfaceB = new Mock<InterfaceB>();
// Then you setup, which will make your ClassB "look like" something you want it to look like
interfaceB.Setup(s => s.setupOfSomeMethod($withArgument1$)).Returns($shouldReturnThisValue$).Verifyable();
InterfaceA classA = new ClassA(interfaceB.Object);
// do your testing here.
答案 1 :(得分:0)
The service locator pattern是处理这种情况的:您可以将所有服务实例放在一个列表中,并使用定位器来获取它们。
对于你的情况,A类依赖于B,B依赖于C.首先,你不应该让类依赖于具体的类,让类依赖于接口。所以A-> IB,B-> IC;然后将具体类放入服务列表中。所以代码会这样:
locator.add(IC, new C());
IC serviceC = locator.find(IC);
if (serviceC )
{ B = new B(serviceC);
locator.add(IB, B);}
要创建A类,只需遵循创建B的例程。因此,当您想使用mock测试A类时,您只需创建两个模拟类,一个继承自IB,一个继承自IC,并将它们输出到服务清单。
答案 2 :(得分:0)