我在.net核心中的userManager有问题,当我在userManager中调用异步方法后使用DI模式进行用户管理和角色管理时,userManager从内存中处理,我无法访问它?!!
你认为我们不能使用依赖注入的异步方法吗?
public interface IUserService
{
IEnumerable<UserViewModel> Read();
Task Update(UserViewModel user);
}
public class UserService : BaseUserService, IUserService
{
private Microsoft.AspNetCore.Http.ISession _session;
private readonly UserManager<ApplicationUser> userManager;
private readonly RoleManager<ApplicationRole> roleManager;
private ApplicationDbContext _context;
public UserService(IHttpContextAccessor httpContextAccessor, ApplicationDbContext context, UserManager<Data.ApplicationUser> userManager, RoleManager<ApplicationRole> roleManager)
{
_session = httpContextAccessor.HttpContext.Session;
this.roleManager = roleManager;
this.userManager = userManager;
_context = context;
}
public async Task Update(UserViewModel user)
{
var target = await userManager.FindByIdAsync(user.Id);
if (target != null)
{
target.Name = user.Name;
target.UserName = user.UserName;
target.Email = user.Email;
var result = await userManager.UpdateAsync(target); // in this line userManager disposed
if (result.Succeeded)
{
}
await ChangePassword(user);
}
}
}
答案 0 :(得分:0)
你认为我们不能使用依赖注入的异步方法吗?
DI和async
是互斥的。 DI主要是通过将依赖注入到消费类的构造函数中来实现的。但是,构造函数永远不会是异步的。这迫使对象图的创建也是同步的。此外,在对象构造期间进行任何I / O都是considered to be a bad practice,所以即使你可以,也不应该这样做。
在您使用依赖项的代码中,没有DI正在进行。此时,对象图已经构建了很长时间(使用DI)。这意味着对已创建的类的方法调用可以是异步的。
但是,每当您忘记await
操作时,此操作将在后台线程上运行,请求线程将继续其操作。由于I / O操作通常很慢,这可能意味着请求在后台线程继续之前完成。在那个时间点,您的DI容器将处理任何请求范围的服务,这可能会破坏您在后台运行的操作。这很可能是你所看到的问题。
始终await
异步操作非常重要,以防止多线程问题和服务从您那里获得处置。
答案 1 :(得分:0)
我使用以下代码解决了这个问题,该代码用于startup.cs中的transient
services.AddTransient<IUserService, UserService>();
我将其更改为作用域:
services.AddScoped<IUserService, UserService>();