如何在多级类层次结构中使用依赖注入?

时间:2014-02-06 12:16:47

标签: design-patterns dependency-injection

如何在多级类层次结构中使用依赖注入? 例如: -

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类???

3 个答案:

答案 0 :(得分:1)

此代码按照我的测试工作。

我建议您使用企业库块Unity,以实现它。 要下载它,请点击此处:http://msdn.microsoft.com/en-us/library/dn169621.aspx,或尝试使用NUget获取它:https://www.nuget.org/packages/EnterpriseLibrary.Common/

  1. 首先,您需要通过使所有类实现接口来更改您的设计。那将是:

    class ClassA : InterfaceA {...}
    class ClassB : InterfaceB {...}
    class ClassC : InterfaceC {...}
    
  2. 添加对这些程序集的引用:

    • Microsoft.Practices.EnterpriseLibrary.Common.dll
    • Microsoft.Practices.ServiceLocation.dll
    • Microsoft.Practices.Unity.dll
    • Microsoft.Practices.Unity.Configuration.dll
    • Microsoft.Practices.Unity.Interception.dll
    • Microsoft.Practices.Unity.Interception.Configuration.dll
  3. 在您真正的实施中,将其放在&#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>();
    
  4. 在您的测试实现中,使用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)