繁体   English   中英

在 .NET Core 上传递带有参数的构造函数作为泛型

[英]Pass constructor with parameter as generic on .NET Core

我有一种更新用户状态的方法

public async Task UpdateStatus<TService, T>(int id, int status)
    where TService : StatusService<T>, new()
{
    await new TService().UpdateStatus(id, status);
}

我的UserService有构造函数

public class UserService : StatusService<User>
{
    public UserService(MyContext context) : base(context)
    {
    }

    ....
}

更新用户状态的操作:

public async Task UpdateUserStatus(int id, int status)
{
    await UpdateStatus<UserService, User>(id, status);
}

然后我的代码有错误:

'UserService' must be a non-abstract type with a public parameterless constructor in order to use it as parameter 'TService' in the generic type or method

如何将带有参数的构造函数作为泛型类型传递?

您的基本问题是,只要您使用的是UserService object,您就需要在要创建MyContext的位置创建一个TService实例。

解决此问题的一种方法是将Func<TService>传递给UpdateStatus()方法,而不是指定new的约束:

public async Task UpdateStatus<TService, T>(int id, int status, Func<TService> serviceCreator)
    where TService : StatusService<T>
{
    await serviceCreator().UpdateStatus(id, status);
}

然后UpdateUserStatus()的实现看起来像这样:

public async Task UpdateUserStatus(int id, int status)
{
    var context = new MyContext(); // However you obtain this.
    await UpdateStatus<UserService, User>(id, status, () => new UserService(context));
}

然后您面临的问题是如何获取创建UserService object 所需的MyContext实例。 您无法避免需要MyContext实例,因为UserService在您创建它时需要它。

这是 DotNetFiddle 上的一个可运行示例。

您可以进一步注入一个委托来创建MyContext object:

public async Task UpdateUserStatus(int id, int status, Func<MyContext> contextProvider)
{
    await UpdateStatus<UserService, User>(id, status, () => new UserService(contextProvider()));
}

现在我们已经将MyContext创建推到了外部级别。 当然,外部级别必须仍然能够获取或创建MyContext

这是一个可运行的示例,其中包含 DotNetFiddle 上的这些更改。

看起来您已设置为在项目中使用 DI,因此您应该使用它。

在您的 Program.cs 中,注册实现基本 class 的类(作为接口可能更好),例如:

builder.Services.AddTransient<StatusService<User>, UserService>();

现在不需要单独的任务来更新状态,只需通过 DI 将您的预期服务传递给您的构造函数,它将自动包含上下文:

public class WhatIsYourClassCalled
{
    private readonly StatusService<User> _statusService;

    public WhatIsYourClassCalled(StatusService<User> statusService)
    {
        _statusService = statusService;
    }

    public async Task UpdateUserStatus(int id, int status)
    {
        await _statusService.UpdateStatus(id, status);
    }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM