我有默认 DI 实现的 Asp.net Core 项目。所以我通过 DI 获得了 BL 服务实例、存储库、EF 上下文。我有通过参数返回特定类型的抽象方法。
IDocumentPreprocessor CreateDocumentPreprocessor(DocType docType)
{
switch (docType)
{
case DocType.Txt:
return new TxtPreprocessor(_context, _docRepository);
case DocType.Doc:
return new DocPreprocessor(_docRepository);
default:
throw new ...
}
}
我不喜欢这里直接通过“new”创建实例。但是我不确定是否可以将此逻辑传递给 DI。所以问题 - 如何将其重构为 DI 使用?
您将逻辑包装在另一个 DI 可注入(inject)服务中:IDocumentPreprocessorFactory
。在那里,您为 IDocumentPreprocessor
实现注入(inject)工厂方法。
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 设置。我还没有使用过 Core 的 DI,但我相信它可能看起来像这样
services.AddSingleton<Func<DocPreprocessor>>(ctx => () => ctx.GetService<DocPreprocessor());
services.AddSingleton<Func<TxtPreprocessor>>(ctx => () => ctx.GetService<TxtPreprocessor());
我是一名优秀的程序员,十分优秀!