2013-10-17 6 views
1

종속성 주입을 사용하고 있으며 알아낼 수없는 것에 대비하여 왔습니다.종속성 주입, 상속 및 generics

public class BaseClass 
{ 
    public BaseClass(ILogger<BaseClass> logger) 
    { 
     // code here 
    } 
} 

그런 다음 나는 또한 일반 로거를 필요로하는 클래스 상속이 : 나는 일반적인 로거를 필요로하는 기본 클래스가

public class SubClass : BaseClass 
{ 
    public SubClass(ILogger<SubClass> logger) 
    { 
     // code here 
    } 
} 

문제는이 메시지와 함께 컴파일되지 않는다는 것입니다; BaseClass에는 0 개의 인수를 취하는 생성자가 포함되어 있지 않습니다..

이 내가 할 수있는 경우 해결하기 쉬운 것입니다이 :

public SubClass(ILogger<SubClass> logger) : base(logger) 

문제는이 정당하지 않은 중 하나 ILogger<SubClass> 이후 ILogger<BaseClass>의 인스턴스 (이 로 가장 과부하가 컴파일되지 않습니다이되지 않는 것입니다 ...에 대한 일부 잘못된 인수가 있습니다).

한 가지 가능한 솔루션 : 은 내가 생성자 주입을 사용하는 대신 DependencyResolver를 사용할 필요가 없습니다 같아요.

질문 : 분명히 다른 사람이 전에이 문제에 대해 제기 한 적이 있습니까? 생성자 삽입 작업이 가능합니까? 그렇다면 무엇을해야합니까?

참고 : 현재 프로젝트에서 나는 StructureMap (for MVC4)를 사용하고,하지만 난 여기에이 도구는 약간 관련이 있다고 생각합니다.

+1

동일한 작업을 수행하기 위해 서로 다른 클래스에 동일한 종속성을 주입하는 경우에는 차단을 살펴볼 수 있습니다. –

+0

@FacioRatio 당신의 통찰력에 감사드립니다. 이후에 나는 매우 흥미로 웠던 http://programmers.stackexchange.com/questions/139111/interception-vs-injection-a-framework-architecture-decision을 읽었다.다른 곳에서 언급했듯이,'ILogger '은 DI를 통해 이미 많은 다른 솔루션과 프로젝트에서 사용되고 있습니다. 그러나 미래의 솔루션을 위해서는 고려해야 할 가치가 있습니다. – Halvard

+0

장식은 좋지만, 같은 일을하는 많은 데코레이터로 끝나면, 차단의시기입니다. 참조 : http://simpleinjector.codeplex.com/wikipage?title=Advanced-Scenarios#Interception –

답변

2

당신은 로거 인터페이스로 변경할 수 :

interface ILogger<out T> where T : BaseClass 
+0

+1 내가봤을 때 내가봤을 때 'out'이 방식으로 사용되어 정말 무슨 일이 일어나고 있는지 생각해야만했다. 그것은 컴파일 문제를 해결했고이 클래스를 사용하는 방식이 문제를 해결하는 유효한 방법이라고 생각합니다. 비록 내 마음이 실제로 이것을 사용하여 결과 주위에 포장되지 않습니다 나는 올바른 답변으로 표시 해요. – Halvard

1

이것은 ILogger<SubClass>ILogger<BaseClass>의 하위 클래스가 아니기 때문에 발생합니다. 따라서 컴파일러는 새로운 생성자를 작성했다고 생각합니다. 이것은 묵시적으로 당신이 쓴 경우

public class SubClass : BaseClass 
{ 
    public SubClass(ILogger<SubClass> logger) 
     : base() // since base class does not have a constructor 
       // with no arguments, you will get the error 
    { 
     // code here 
    } 
} 

그래서 당신의 질문은 정확하게 의존성 주입에 관한 것이 아닙니다. 그것은 당신의 아키텍처에 관한 것입니다.

+0

이것이 아키텍처 문제 일 수 있으며 (오류 메시지를 이해할 수 있음) 동의 할 수는 있지만 이 일반 클래스 ('Ilogger ')를 사용하여 생성자를 통해 DI를 사용 하시겠습니까? – Halvard

+0

DI는 수동으로 할 수있는 작업을 자동화하는 도구 일뿐입니다. 만약 당신이 코드를 컴파일 할 수 있다면 DI를 사용할 수 있습니다. 저는 정말로 ILogger에 제네릭 파라미터가 필요하다고 생각하고 싶습니다. –

+0

'ILogger'가 너무 많은 프로젝트에서 일반이 아닌 것으로 변경하려고합니다. 잘 사용되는 오래된 레거시 코드입니다. 어쨌든 귀하의 의견을 보내 주셔서 감사합니다! – Halvard

1

당신은 매개 변수가있는 생성자를 호출하고 수동으로 해결 ILogger 예를 전달할 것이다 당신의 BaseClass에 매개 변수가없는 생성자를 추가 할 수 있습니다. 이 같은 뭔가 : 유형 BaseClass의 인스턴스가 해결되면

public BaseClass() 
    : this(ResolveLogger()) 
{ 
} 

private static ILogger<BaseClass> ResolveLogger() 
{ 
    // resolve the instance manually and return it 
} 

이 방법, 매개 변수화 된 생성자를 사용하고 해결 ILogger<BaseClass> 인스턴스를 주입 할 것이다. 그러나 파생 클래스가 해결되면이 파생 클래스는 매개 변수없는 BaseClass() 생성자를 호출하고 ILogger<BaseClass>은 수동으로 확인됩니다.

+0

+1이 방법을 사용하면 문제를 해결할 수 있습니다. 로거를 수동으로 해결하지 않고도 문제를 해결하려고 했으므로 올바른 답을 확인하는 다른 답변을 제공하고 있습니다. 도와달라고 Thnaks! – Halvard