简体   繁体   English

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

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

I have a method to update the user status我有一种更新用户状态的方法

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

My UserService have constructor我的UserService有构造函数

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

    ....
}

Action to update user status:更新用户状态的操作:

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

Then my code have the error:然后我的代码有错误:

'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

How do I pass the constructor with parameter as generic type?如何将带有参数的构造函数作为泛型类型传递?

Your fundamental issue is that you need an instance of MyContext at the point where you want to create the TService , as long as you are using a UserService object.您的基本问题是,只要您使用的是UserService object,您就需要在要创建MyContext的位置创建一个TService实例。

One way to solve this is to pass in a Func<TService> to the UpdateStatus() method instead of specifying the new restraint:解决此问题的一种方法是将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);
}

Then the implementation of UpdateUserStatus() would look something like this:然后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));
}

The issue you then face is how to obtain the MyContext instance that you need for creating the UserService object.然后您面临的问题是如何获取创建UserService object 所需的MyContext实例。 You can't avoid the need for the MyContext instance because the UserService requires it when you create it.您无法避免需要MyContext实例,因为UserService在您创建它时需要它。

Here's a runnable example on DotNetFiddle.这是 DotNetFiddle 上的一个可运行示例。

You can take a further step of injecting a delegate with which to create the MyContext object:您可以进一步注入一个委托来创建MyContext object:

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

Now we've pushed the MyContext creation to the outer level.现在我们已经将MyContext创建推到了外部级别。 The outer level must still be able to obtain or create a MyContext , of course.当然,外部级别必须仍然能够获取或创建MyContext

Here's a runnable example with those changes on DotNetFiddle.这是一个可运行的示例,其中包含 DotNetFiddle 上的这些更改。

Looks like you're set up to use DI in your project, so you should use it.看起来您已设置为在项目中使用 DI,因此您应该使用它。

In your Program.cs, register your classes that implement your base class (which could be better as an interface), eg:在您的 Program.cs 中,注册实现基本 class 的类(作为接口可能更好),例如:

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

Now instead of having a separate task to update the status, just pass your expected service into your constructor via DI which will automatically include the context:现在不需要单独的任务来更新状态,只需通过 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.

相关问题 传入类型作为构造函数参数或泛型 - Pass In Type as Constructor Parameter or Generic 在通用约束中通过构造函数传递参数 - Pass parameter through constructor in generic constraints 如何将Generic类作为参数传递给非泛型类构造函数 - How to pass a Generic class as a Parameter to a non-generic class constructor .Net Core DI 将运行时参数传递给服务的构造函数,也传递给它的 1-n 个子服务 - .Net Core DI pass runtime parameter into constructor of service and also into 1-n of its' subservices 在.net核心中使用构造函数参数进行依赖注入 - Dependency injection with constructor parameter in .net core .NET CORE 依赖注入将参数传递给构造函数 - .NET CORE dependency injection passing parameter to constructor .net core 3.0 构造函数参数问题 - .net core 3.0 Constructor parameter problem .NET Core 3 ExceptionHandler 与 Generic Logger 参数 - AmbiguousMatchException - .NET Core 3 ExceptionHandler with Generic Logger parameter - AmbiguousMatchException dotnet .net core 2 OrderBy/OrderByDescending 带泛型参数 - dotnet .net core 2 OrderBy/OrderByDescending with generic parameter .net:在注入对象的构造函数中传递字符串参数 - .net: pass string parameter in the constructor of an injected object
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM