Reputation: 23
How to use Dependency Injection in multilevel class hierarchy? For example :-
public class ModuleClassViewModel
{
ModulePageClassServiceRepository _modulePageClassServiceRepository = null;
public ModuleClassViewModel(ModulePageClassServiceRepository modulePageClassServiceRepository)
{
_modulePageClassServiceRepository = modulePageClassServiceRepository;
}
public IList<ModulePageClassObject> ModuleClassPageHierarchy(int? modulePageClassID, string SecureKey)
{
return _modulePageClassServiceRepository.ModuleClassPageHierarchy(....);
}
}
and code for ModulePageClassServiceRepository is.......
public class ModulePageClassServiceRepository : IModulePageClassService
{
ServiceDAO _serviceDAO = null
public ModulePageClassServiceRepository(ServiceDAO serviceDAO )
{
serviceDAO = serviceDAO ;
}
public IList<ModulePageClassObject> ModuleClassPageHierarchy(ModuleClassPageHierarchyParameter moduleClassPageHierarchyParameter)
{
// call serviceDAO and return result
}
}
now as per DI if we want to use ModuleClassViewModel then we first need to inject ModulePageClassServiceRepository object and for ModulePageClassServiceRepository we need serviceDAO .... this hierarchy can grow to multiple level.... assume in 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
}
}
Is this correct way to use dependency injection. here I need to first initialize complete hierarchy so my question is - Do I need to first initialize this complete hierarchy....or is there any other way to call ModuleClassViewModel class ???
Upvotes: 2
Views: 2001
Reputation: 169
IocServiceStack supports multi-level dependency injection.
https://github.com/rjinaga/IocServiceStack
http://www.iocservicestack.net/
Upvotes: 0
Reputation: 911
This code is working as per my tests.
I suggest you use the Enterprise library block Unity, in order to make it happen. To download it click here: http://msdn.microsoft.com/en-us/library/dn169621.aspx, or try to get it using NUget: https://www.nuget.org/packages/EnterpriseLibrary.Common/
First of all, you need to change your design by making all classes to implement an interface. That would be:
class ClassA : InterfaceA {...}
class ClassB : InterfaceB {...}
class ClassC : InterfaceC {...}
Add references to these assemblies:
In your real implementation put this in your start of the "ClassA" caller: (see more 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>();
In your test implementation, using the Moq framework (https://code.google.com/p/moq/) you will be able to do this:
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.
Upvotes: 1
Reputation: 6050
The service locator pattern is to deal with this case: you can put all your service instance in a list, and use the locator to get them.
For you case, Class A depends on B, B depends on C. First, you should not let class depends on concrete classes, let classes depends on the interfaces. So A->IB, B->IC; then put the concrete classes into the service list. So the code will like this:
locator.add(IC, new C());
IC serviceC = locator.find(IC);
if (serviceC )
{ B = new B(serviceC);
locator.add(IB, B);}
To create the class A, just follow the routine of creating B. So when you want to test class A using mock, you just just create two mock classes, one inherit from IB, one inherit from IC, and out them into the service list.
Upvotes: 0