【问题标题】:Trying to follow .AddService & .UseService pattern试图遵循 .AddService 和 .UseService 模式
【发布时间】:2022-08-10 18:15:50
【问题描述】:

在我的 Minimal API 中,我使用 Kofax TotalAgility WCF 端点并与之集成。我想正确地实现这个集成,所以我添加了一个远程程序集,并在其中添加了 WCF 合同以及服务接口和实现:

服务接口:

public interface IKofaxService
{
    public Task<string> CreateJob(long letterId);
    public Task ActionHandler(PortalActionRequest request);
}

服务实现:

public class KofaxService : IKofaxService
{
    private readonly ILogger<KofaxService> logger;
    private readonly KofaxSetup            config;

    private readonly KtaJob.IJobService           jobService;
    private readonly KtaActivity.IActivityService activityService;

    public KofaxService(ILogger<KofaxService> inLogger, KofaxSetup inConfig)
    {
        logger = inLogger;
        config = inConfig;

        //WCF Generated Stuff within this remote assembly
        jobService      = new KtaJob.JobServiceClient(GetBinding(), GetEndpointAddress(config.KtaUrlApiJob)); 
        activityService = new KtaActivity.ActivityServiceClient(GetBinding(), GetEndpointAddress(config.KtaUrlApiActivity));
    }

    public async Task<string> CreateJob(long letterId)
    {
        ...
    }

    public async Task ActionHandler(PortalActionRequest request)
    {
        ...
    }
}

为了拥有Servces.AddKofaxTotalAgility() 之类的 fluent API,我添加了这样的扩展方法(在远程程序集中): 服务扩展方法:

public static class ServiceCollectionExtensions
{
    public static IServiceCollection AddKofaxTotalAgility(this IServiceCollection services)
    {
        services.AddScoped<IKofaxService, KofaxService>();
        return services;
    }
}

同样在远程程序集中,我有一个代表 appSettings 部分的设置对象的类:

配置类:

public class KofaxSetup
{
    public string KtaUrlApiActivity { get; set; } = string.Empty;
    public string KtaUrlApiJob      { get; set; } = string.Empty;
    public string SessionId         { get; set; } = string.Empty;
    public string ProcessId         { get; set; } = string.Empty;
}

回到 Minimal API 项目,我添加了对远程程序集的引用,并且在 appSettings.json 文件中也有设置:

appSettings.json:

{
  ...  
  \"KofaxSetup\": {
    \"KtaUrlApiActivity\": \"https://kofax.somewhere.com/TotalAgility/Services/SDK/ActivityService.svc\",
    \"KtaUrlApiJob\": \"https://kofax.somewhere.com/TotalAgility/Services/SDK/JobService.svc\",
    \"SessionId\": \"7DB87F70018D4770BF6114B1C9BA6041\",
    \"ProcessId\": \"66EC6EED5D024E7AB0013D60F7A04A1A\"
  },
  ...
}

最后,对Program.cs的修改如下:最小 API Program.cs

var builder = WebApplication.CreateBuilder(args);
...
// Trigger KofaxSetting object from AppSetting\'s section
builder.Services.Configure<KofaxSetup>(builder.Configuration.GetSection(nameof(KofaxSetup)));
...
// Add the service to the DI
builder.Services.AddKofaxTotalAgility();
...

所有这些只会在启动时导致此异常:

异常@var app = builder.Build();

System.AggregateException: \'Some services are not able to be constructed (Error while validating the service descriptor \'ServiceType: DACRL.Integrations.Kofax.IKofaxService Lifetime: Scoped ImplementationType: DACRL.Integrations.Kofax.KofaxService\': Unable to resolve service for type \'DACRL.Integrations.Kofax.Configs.KofaxSetup\' while attempting to activate \'DACRL.Integrations.Kofax.KofaxService\'.) (Error while validating the service descriptor \'ServiceType: DACRL.Application.Core.Services.ILetterService Lifetime: Transient ImplementationType: DACRL.Api.Services.LetterService\': Unable to resolve service for type \'DACRL.Integrations.Kofax.Configs.KofaxSetup\' while attempting to activate \'DACRL.Integrations.Kofax.KofaxService\'.) (Error while validating the service descriptor \'ServiceType: DACRL.Application.Core.Services.ILetterService Lifetime: Transient ImplementationType: DACRL.Api.Services.LetterService\': Unable to resolve service for type \'DACRL.Integrations.Kofax.Configs.KofaxSetup\' while attempting to activate \'DACRL.Integrations.Kofax.KofaxService\'.)\'

1/2:
InvalidOperationException: Error while validating the service descriptor \'ServiceType: DACRL.Integrations.Kofax.IKofaxService Lifetime: Scoped ImplementationType: DACRL.Integrations.Kofax.KofaxService\': Unable to resolve service for type \'DACRL.Integrations.Kofax.Configs.KofaxSetup\' while attempting to activate \'DACRL.Integrations.Kofax.KofaxService\'.

2/2:
InvalidOperationException: Unable to resolve service for type \'DACRL.Integrations.Kofax.Configs.KofaxSetup\' while attempting to activate \'DACRL.Integrations.Kofax.KofaxService\'.

请注意 ILetterService 工作正常,这是内部尝试在其参数中从 DI 接收 IKofaxService 的服务。我认为该错误与 KofaxSetup 对象有关

我在这里缺少最佳实践吗?我应该在某个地方有一个无参数的构造函数吗?服务实现中的Logger&lt;KofaxService&gt; 注入是否无效?

    标签: asp.net-core-7.0


    【解决方案1】:

    我实际上解决了这个问题,但不想浪费一个写得很好的问题。

    问题是事实,KofaxSetup 类。我直接在服务的构造函数中接收它作为它的类型。我不得不改用IOptions&lt;KofaxSetup&gt; 来解决这个问题。

    【讨论】: