기본 DI 구현을 사용하는 Asp.net 핵심 프로젝트가 있습니다. 그래서 BL 서비스 인스턴스, 리포지토리, EF 컨텍스트를 DI로 얻습니다. 매개 변수별로 특정 형식을 반환하는 추상 메서드가 있습니다.추상 메소드를 DI로 리팩터링하는 법
"new"로 인스턴스를 직접 생성하는 것을 좋아하지 않습니다. 하지만이 논리를 DI로 전달할 수 있는지 확실하지 않습니다. 질문 - DI 사용법을 리팩터링하는 방법은 무엇입니까?
기본 DI 구현을 사용하는 Asp.net 핵심 프로젝트가 있습니다. 그래서 BL 서비스 인스턴스, 리포지토리, EF 컨텍스트를 DI로 얻습니다. 매개 변수별로 특정 형식을 반환하는 추상 메서드가 있습니다.추상 메소드를 DI로 리팩터링하는 법
"new"로 인스턴스를 직접 생성하는 것을 좋아하지 않습니다. 하지만이 논리를 DI로 전달할 수 있는지 확실하지 않습니다. 질문 - DI 사용법을 리팩터링하는 방법은 무엇입니까?
로직을 또 다른 DI 주사 가능 서비스로 포장하십시오 (IDocumentPreprocessorFactory
). 여기에 IDocumentPreprocessor
구현을위한 팩토리 메소드가 삽입됩니다.
public interface IDocumentPreprocessorFactory
{
IDocumentPreprocessor CreateDocumentPreprocessor(DocType docType);
}
public class DocumentPreprocessorFactory : IDocumentPreprocessorFactory
{
private readonly Func<TxtPreprocessor> createTxtPreprocessor;
private readonly Func<DocPreprocessor> createDocPreprocessor;
public DocumentPreprocessorFactory(
Func<TxtPreprocessor> createTxtPreprocessor,
Func<DocPreprocessor> createDocPreprocessor)
{
this.createTxtPreprocessor = createTxtPreprocessor;
this.createDocPreprocessor = createDocPreprocessor;
}
public IDocumentPreprocessor CreateDocumentPreprocessor(DocType docType)
{
switch (docType)
{
case DocType.Txt:
return this.createTxtPreprocessor();
case DocType.Doc:
return this.createDocPreprocessor();
default:
throw new...
}
}
}
이제 공장 설정의 등록으로 DI 설정을 확장해야합니다. 아직 코어의 DI를 사용하지 않은,하지만 난 .. 그것이 당신을 도울 수있다이
services.AddSingleton<Func<DocPreprocessor>>(ctx =>() => ctx.GetService<DocPreprocessor());
services.AddSingleton<Func<TxtPreprocessor>>(ctx =>() => ctx.GetService<TxtPreprocessor());
처럼 보일 수있는 등록 된 클래스의
// object lifetime transient or others.. determine according to your needs
services.AddTransient<TxtPreprocessor>();
services.AddTransient<DocPreprocessor>();
services.AddTransient(processorFactory =>
{
Func<DocType, IDocumentPreprocessor> factoryFunc = docType =>
{
switch (docType)
{
case DocType.Txt:
return processorFactory.GetService<TxtPreprocessor>();
default:
return processorFactory.GetService<DocPreprocessor>();// DocPreprocessor is defult
}
};
return factoryFunc;
});
사용을 .. 생각
public class AnyClass
{
private readonly IDocumentPreprocessor _documentProcessor;
public AnyClass(Func<DocType, IDocumentPreprocessor> factoryFunc)
{
_documentProcessor = factoryFunc(DocType.Doc);
}
}
원하는 경우 팩토리 클래스로이 함수를 캡슐화 할 수 있습니다.
OP가 DocType.Pdf와 같은 새로운'DocType'을 원한다면 어느 시점에서, DocumentPreprocessorFactory 클래스에서 변경이 필요하지 않습니까? 새로운 유형을 추가하는 것이 합리적으로 간단한 변화이지만, Pdf 기능을 추가하기위한 새로운 로직을 포함하도록'DocumentPreprocessorFactory' 클래스를 변경하는 것은 Open Closed 원칙을 위반하지 않을까요? OP가 궁극적으로'DocType.Xml'을 원한다면 같은가? –
@ mike-maurer, 당신 말이 맞습니다. 그러나 OP의 'switch'블록을 리팩토링하는 것은 완전히 다른 이야기이다. –
흥미 롭습니다. 솔리드 원칙을 위반하지 않고이를 해결하는 구현이 있는지 궁금 할 것입니다. –