CS1503 "cannot convert" 注册泛型类型时出现编译错误

CS1503 "cannot convert" compile error when registering generic type

如何在ASP.NET核心项目中正确实现依赖注入?项目中有一个认证服务,我需要创建两个实现。首先使用假数据,然后使用数据库。

接口:

public interface IAuthenticationService<TRequest, TResponse> : IService
    where TRequest : IRequest
    where TResponse : IResponse
{
    Task<TResponse> Auth(TRequest request);
}

两个这样的实现:

public class DummyAuthenticationService<TRequest, TResponse>
    : IAuthenticationService<TRequest, TResponse>
    where TRequest : AuthenticateRequest
    where TResponse : AuthenticateResponse
{
    public Task<TResponse> Auth(TRequest request)
    {
        throw new NotImplementedException();
    }
}

控制器:

[HttpPost]
public async Task<IResponse> AuthenticationViaYouTube(AuthenticateRequest parr)
{
    AuthenticateResponse response = (AuthenticateResponse) await _authenticationService.Auth(parr);
    return response;
}

Startup.cs:

public void ConfigureServices(IServiceCollection services)
{
    #if DEBUG
    services.AddSingleton<IAuthenticationService<IRequest, IResponse>>
        (new DummyAuthenticationService<AuthenticateRequest, AuthenticateResponse>());
    #elif Release
    services.AddSingleton<IAuthenticationService<IRequest, IResponse>>
        (new DBAuthenticationService<AuthenticateRequest, AuthenticateResponse>());
    #endif
}

但是我得到一个编译器错误:

Error CS1503 Argument 2: cannot convert from 'DummyAuthenticationService<AuthenticateRequest, AuthenticateResponse>' to 'System.Func<System.IServiceProvider, IAuthenticationService<IRequest,IResponse>>'

您收到编译错误的原因与此代码会给您带来编译错误的原因相同:

IAuthenticationService<IRequest, IResponse> service =
    new DummyAuthenticationService<AuthenticateRequest, AuthenticateResponse>();

C# 编译器告诉您创建的实例无法转换为 IAuthenticationService<IRequest, IResponse>

这与方差有关。协变和逆变是一个复杂的话题,我很难用几句话来解释。关于这个主题实际上有很棒的 Microsoft 文档,我鼓励您查看。

虽然可以用 inout 参数标记支持变体接口,但这不会让您的代码编译。相反,要进行此编译,您必须将代码更改为以下内容:

IAuthenticationService<AuthenticateRequest, AuthenticateResponse> service =
    new DummyAuthenticationService<AuthenticateRequest, AuthenticateResponse>();

因此,您的 ConfigureServices 方法如下:

services
  .AddSingleton<IAuthenticationService<AuthenticateRequest, AuthenticateResponse>>(
     new DummyAuthenticationService<AuthenticateRequest, AuthenticateResponse>());

或者,或者:

services.AddSingleton(
    typeof(IAuthenticationService<,>),
    typeof(DummyAuthenticationService<,>));

我相信您遇到了编译错误,因为无法解析 IRequest 和 IResponse。我不认为在尝试使用 DI 进行绑定时可以提供接口作为泛型。尝试提供 concreate 类.

services.AddSingleton<IAuthenticationService<AuthenticateRequest, AuthenticateResponse>>
        (new DummyAuthenticationService<AuthenticateRequest, AuthenticateResponse>());

至于你的“if debug”问题——有 1000 种不同的方法可以解决这个问题。我个人更喜欢让 appSettings 决定而不是调试器评论。

这是我的做法。

  • 有两个 appsettings.json 文件,一个用于开发,一个用于生产。
  • 添加一个名为“MockServices”之类的布尔值。
  • 根据布尔值更改绑定。

这样做的好处是,如果需要,您可以轻松地在生产环境中模拟服务。

如果您需要我扩展任何内容,请告诉我。