簡體   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