1

종속성 주입의 기본 사항을 알고 있지만 Unity를 사용하여 MVC API C# 응용 프로그램에 올바르게 넣으려고 애 쓰고 있습니다. 내가 가진 문제는 내가 방법을 가진 컨트롤러를 가지게 될 것이고, 그 방법에서는 두 개의 객체를 말할 것입니다. 이러한 개체 중 하나는 데이터 액세스 계층에 대한 종속성을 가지며 다른 개체는 그렇지 않습니다. 정확히 어떻게 설정해야하는지 잘 모르겠습니다.Unity와 종속성 삽입 런타임 매개 변수로 생성자를 사용하여

내가 검색 개체에서 사용자를 가져 오는 다음과 같은 방법으로 컨트롤러가 있다고 가정 해 보겠습니다. 또한 SearchParameters 객체를 사용하여 검색을 수행합니다. 이름없이 검색하면 모든 결과를 얻습니다. 이름을 입력하면 해당 이름을 가진 사용자가됩니다.

public Users[] GetUsers(string name) { 
    Company.SearchParameters searchParams = new Company.SearchParameters(name); 
    Company.UserSearchService searchService = new Company.UserSearchService(searchParams); 

    return searchService.Search(); 
} 

물론 이것은 매우 단순화 된 버전이지만이 경우 Search 메서드의 UserSearchService는 명시 적 데이터베이스 호출을 수행하고 있습니다. 그래서 나는 그것이 그것을 줄 필요가있는 의존성이라는 것을 압니다. SearchParameters는 실제로 데이터를 보유하는 클래스 일뿐입니다.

다음은 정확히 어떻게 해야할지 잘 모르겠습니다. 컨트롤러 자체에는 의존성이 없지만 UserSearchService는 유니티를 사용하는 방법을 잘 모르겠습니다. 올바르게 설정하고 생성자의 런타임 값을 고려합니다. 또한 SearchParameters가 종속성으로 간주되는지 아닌지 잘 모르겠습니다.

또한 SearchParameters 및 UserSearchService에는 문제가있는 경우이 컨트롤러에는 아마도 Company.UserAccount와 같이 비슷한 데이터 액세스 계층 종속성이 필요한 다른 클래스와 상호 작용하는 다른 메서드가 있습니다.

+0

당신의 코드'Company.UserSearchService'에 따르면 (? 또는 당신이 뭔가를 생략) Company.SearchParameters''를 제외하고 종속성이 없습니다하지만 당신은 _The 컨트롤러 자체가 의존성을 가지고 있지만 있기 때문에하지 않는 말 UserSearchService does_ – neleus

+0

UserSearchService의 Search 메서드에는 Database.Execute에 대한 명시적인 호출이 있습니다.이 메서드는 데이터베이스에 도달하여 현재 종속성이있는 정적 메서드입니다. 이 문제를 해결하여 실제로 테스트 할 수 있습니다. – Topojijo

답변

0

여기 두 가지 작업이 있습니다. 첫 번째는 정적 종속성을 인터페이스로 대체해야하는 리팩터링입니다. 두 번째 작업은 IoC 컨테이너에 물건을 등록하는 것입니다. 첫 번째 작업에 대한

당신이 필요로하는 최소가 (그것도 조롱 할 수 있도록) 귀하의 UserSearchServiceIDatabase 인터페이스 Database에 대한 모든 참조를 대체하고이 생성자 (생성자 주입)에 전달 될 수 있도록하는 것입니다. 서비스에 IDatabase의 인스턴스를 제공하려면 컨트롤러에 대해 동일한 종속성을 생성해야합니다 (다시 생성자 삽입). 그런 다음 this post과 같이 IDatabase 구현을 등록하십시오.

업데이트는 그 의존성이 컨트롤러에서 제거해야합니다 동의합니다. @Topojijo가 제안한 공장은 UserSearchService을위한 공장을 사용할 수 있습니다. 각각에 대한 팩토리를 만드는 데 필요한 몇 가지 핵심 기능이 있으며 추세가 클 경우 오버 헤드가 발생할 수 있습니다. 이러한 경우는 유니티 컨테이너에서 resolve the service directly하는 것이 좋습니다과 searchParamsSearch에 대한 방법을 이동 :

public Users[] GetUsers(string name) { 
    Company.SearchParameters searchParams = new Company.SearchParameters(name); 
    Company.UserSearchService searchService = container.Resolve<Company.UserSearchService>(); 

    return searchService.Search(searchParams); 
} 
+0

그게 처음에 생각한 것입니다.하지만 컨트롤러에 종속성을 전달하는 것은 컨트롤러 자체가 결코 그 의존성을 사용하지 않기 때문에 잘못된 것입니다. 내가 본 것은 본질적으로 컨트롤러가 UserSearchService를 빌드하는 팩토리를 전달 받고 그 팩토리에서 Unity를 사용하는 것입니다. – Topojijo

+0

그래, 맞아.이게 더 진보 된 해결책이야. 나는 나의 대답을 업데이트했다. – neleus

0

매개 변수를 생성자의 일부가 될 수 없습니다해야 검색; 그것은 "검색"방법의 일부 여야합니다. SearchParameter 객체는 UserSearchService 클래스 (캡슐화) 외부에서도 알 수 없습니다. neleus가 제안한 것처럼 리팩터링이 있어야합니다. 적어도, 가지가이 비슷한에 리팩토링해야한다, 가야 :

public Users[] GetUsers(string name) { 
    // Or however you end up with your UserSearchService object. 
    // Ideally as an interface and an injected dependency... 
    Company.UserSearchService searchService = new Company.UserSearchService(); 

    return searchService.Search(name); 
} 

회사.UserSearchService :

public Users[] Search(string name) { 
    // A factory would be a better option. This should also be an interface. 
    Company.SearchParameters searchParams = new Company.SearchParameters(name); 

    // Your logic here 
} 
관련 문제