1

두 가지 프로젝트가있는 솔루션이 있으므로 DI 문제가 발생했습니다. 솔루션은 클래스 라이브러리와 WebApi2 앱 (클래스 라이브러리를 사용하고 API를 노출 함)으로 구성됩니다.클래스 라이브러리의 의존성 삽입

프로젝트의 모든 DI를 설정하는 클래스 라이브러리에 Autofac.module을 정의했습니다.

WebApi2 프로젝트에서 (Autofac.WebApi2를 사용하여) DI 컨테이너를 만들고 클래스 라이브러리에서 모듈을로드합니다. 이제 WepApi2 프로젝트의 API 컨트롤러가 클래스 라이브러리에서 서비스를 요청할 때 모든 의존성을 사용하여 만들면이 모든 것이 효과적입니다!

문제는 클래스 라이브러리가 문자열에서 일부 클래스를 인스턴스화해야한다는 것입니다. 이제는 리플렉션을 사용하여이 작업을 수행하는 유일한 방법을 알고 있습니다. 이 같은 :

var ruleType = Type.GetType(rule.RuleImplementation.Implementation); 
var rule = (IRule)Activator.CreateInstance(ruleType,param1,param2); 

문제는 아이 룰 인터페이스를 구현하는 클래스도 해결하는 데 필요한 종속성을 가지고 있다는 것입니다,이 날 지금 잠시 동안 내 키보드 내를 두드리는 만든 것입니다.

어쨌든 리플렉션과 autoFac을 함께 사용하여 객체를 인스턴스화 할 수 있습니까? 나는 여전히 개체에 내 매개 변수를 전달할 수 있어야합니다.

... 또는 어떻게 든 (webApi2 어셈블리에서 생성 된) 컨테이너에 액세스하여이를 해결하는 방법이 있습니까? 이 패턴이 안티 패턴으로 여겨지는 것이라고 생각합니다.

어떻게 진행합니까? 모든 입력은 매우 감사드립니다.

답변

2

Activator.CreateInstance을 사용하여 구성 요소를 만드는 것은 기본적으로 컨테이너가 사용자를 위해 수행하는 로직을 다시 구현하지만 DI 라이브러리가 제공하는 기능 및 안전 가드가 없으므로 바람직하지 않습니다.

프로젝트의 모든 DI를 설정하는 클래스 라이브러리에 Autofac.module을 정의했습니다.

여기가 문제의 근원입니다. 객체 그래프가 구성되고 등록되는 응용 프로그램에는 하나의 위치 만 있어야하며 이는 응용 프로그램의 Composition Root입니다. 이 Composition Root는 Composition Root (레이어)와 Presentation Layer를 동일한 프로젝트에 두는 것이 매우 일반적 임에도 불구하고 프리젠 테이션 레이어 (웹 API) 위에있는 별도의 레이어로 볼 수 있습니다.

이렇게하면 컨테이너 루트에 이미 컨테이너에 액세스 할 수 있기 때문에 문제가 해결됩니다.

데이터베이스에서 오는 일부 정의를 사용하여 규칙을 만들 수있는 좋은 해결책은 IRuleActivator 추상화를 정의하는 것입니다. 이 추상화는 라이브러리에서 정의하고 컴포지션 루트 내부에서 구현할 수 있습니다.라이브러리가 컨테이너의 존재를 망각 유지하면서는 컨테이너를 포장하는 구현을 할 수 있습니다 :

// Defined in the library 
public interface IRuleActivator 
{ 
    IRule GetRule(RuleData rule); 
} 

// Defined in the Compostion Root 
public sealed class AutofacRuleActivator : IRuleActivator 
{ 
    private readonly IComponentContext context; 
    public AutofacRuleActivator(IComponentContext context) { 
     this.context = context; 
    } 

    public IRule GetRule(RuleData rule) { 
     Type ruleType = Type.GetType(rule.RuleImplementation.Implementation); 
     return (IRule)this.context.Resolve(ruleType); 
    } 
} 
당신은 아이 룰 작성을위한 공장을 만들 수 있습니다
1

: 나는 몇 가지로 갈 것 매개 변수의

public IRuleFactory 
{ 
    IRule CreateRule(params); 
} 

IRalFactory의 구현에 삽입 할 수있는 IParamsProviders의 종류 인 RuleImpl은 객체 구조를 구현 한 것으로 반사도 가능합니다.

이러한 인터페이스를 Ioc에 등록하고이를 서비스 핸들러에 주입하십시오.

+0

나는이 솔루션을 좋아한다. 제가 아는 한 유일한 단점은 런타임에 데이터베이스를 쿼리 할 때 먼저 알기 때문에 필요한지 여부에 관계없이 모든 규칙을 내 서비스에 삽입해야한다는 것입니다. – iCediCe