[英]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
在您创建它时需要它。
您可以进一步注入一个委托来创建MyContext
object:
public async Task UpdateUserStatus(int id, int status, Func<MyContext> contextProvider)
{
await UpdateStatus<UserService, User>(id, status, () => new UserService(contextProvider()));
}
现在我们已经将MyContext
创建推到了外部级别。 当然,外部级别必须仍然能够获取或创建MyContext
。
看起来您已设置为在项目中使用 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.