2014-02-06 2 views
1

다중 레벨 클래스 계층 구조에서 Dependency Injection을 사용하는 방법은 무엇입니까? 예를 들어 : - ModulePageClassServiceRepository에 대한다중 레벨 클래스 계층 구조에서 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 개체를 삽입 할 필요가 ModuleClassViewModel를 사용하려면 DI에 따라 지금
public class ModulePageClassServiceRepository : IModulePageClassService 
    { 
     ServiceDAO _serviceDAO = null 
     public ModulePageClassServiceRepository(ServiceDAO serviceDAO) 
     { 
      serviceDAO = serviceDAO ; 
     } 

     public IList<ModulePageClassObject> ModuleClassPageHierarchy(ModuleClassPageHierarchyParameter moduleClassPageHierarchyParameter) 
     { 
      // call serviceDAO and return result 
     } 
} 

및 ModulePageClassServiceRepository 위해 우리는 .... 는 테스트 클래스에서 가정 .... serviceDAO이 ....이 계층 구조가 여러 수준으로 성장할 수있는 필요

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

당신은 제대로 구성 할 때 수동으로 의존성 주입을 위해, 그것은 필요성을 제거 등 유니티, Autofac, 같은 DI 컨테이너를 사용해야합니다. 또한 클래스에 대한 인터페이스를 작성하면 DI 프로세스가 쉬워지고 코드를보다 유연하게 만들 수 있습니다. –

답변

1

이 코드는 테스트 한 내용입니다.

엔터 프라이즈 라이브러리 블록 유니티를 사용하는 것이 좋습니다. 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.Uni ty.Interception.dll
    • Microsoft.Practices.Unity.Interception.Configuration.실제 구현에서 DLL
  3. 가 "를 ClassA"발신자의 당신의 시작이를 넣어 : 가 (자세한 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. 
    
+0

이 솔루션을 이용해 주셔서 감사합니다. 이것은 제가 찾고 있던 정확한 것입니다. – SAL

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. 그래서, 당신은 단지 두 모의 클래스를 만들 작성하는 루틴, 한 상속에서 다음 클래스 A를 만들려면 IB로부터 하나의 IC를 상속 받아 서비스 목록에 추가합니다.

+0

내가 다시이 질문을 설명하자 ..... 나는 세 클래스 A, B, C를 가지고이 클래스는 A -> B -> C로 서로에 따라 달라집니다 그래서 우리는 클래스 A를 사용하려는 경우 코드에서 첫 번째 우리는 클래스 B에 의존성 클래스 B를 주입하고 클래스 B에 의존성 클래스 C를 주입 할 필요가 있습니다 ... 이것은 일반적인 의존성 주입에서 어떻게 작동합니까? 그리고이 체인 의존성은 Mocking을 사용하여 클래스 A를 테스트하려고 할 때 더 복잡합니다 ...... 나는이 경우 Service Locator Pattern이 작동하지 않을 것이라고 생각한다 ... – SAL

+0

@SAL, 답변에서 내 업데이트를 참조하십시오. – Matt

+0

매트, 빠른 응답을 보내 주셔서 감사합니다. [Service Locator 패턴] (http://stackoverflow.com/questions/1557781/whats-the-difference-between-thependency-injection-and-service-locator-patte)을 이해하려고했습니다. 하나의 문제를 해결합니다 (체인 종속성). 하지만 서비스 로케이터가있는 코드에 대해 모의 객체를 만들 수 없기 때문에 모의 객체를 사용하여 유닛 테스트 케이스에서이 코드를 테스트 할 수 있습니까 – SAL

관련 문제