gpt4 book ai didi

c# - SignalR 和 ASP.NET Identity 的 UserManager 类生命周期

转载 作者:太空宇宙 更新时间:2023-11-03 23:45:23 29 4
gpt4 key购买 nike

在我的 MVC 应用程序中,我使用 SignalR 在用户之间进行通信。基本上,客户端调用集线器上的方法,集线器调用存储库上的方法,然后将消息保存到数据库,集线器将新消息通知其他客户端。

我用过 GetOwinContext()客户端调用这些方法以获取 UserManager 的当前实例和 ApplicationDbContext , 通过使用 GetUserManager<UserManager>()Get<ApplicationDbcontex>()扩展方法,分别。但是,我注意到来自同一连接的调用使用相同的上下文,这显然不是一件好事。我继续更改我的存储库,所以现在是这样的:

    public XyzRepository()  //constructor
{
db = ApplicationDbContext.Create(); //static method that generates a new instance
}
private ApplicatonDbContext db { get; set; }
private UserManager UserManager
{
get
{
return new UserManager(new UserStore<ApplicationUser>(db)); //returns a new UserManager using the context that is used by this instance of the repository
}
}

由于我引用了 ApplicationUser使用 UserManager 的对象(使用 FindByIdAsync() 等,具体取决于设计),将我当前使用的上下文用于 UserStore 非常重要。的 UserManager的当前实例。每个请求创建一次存储库,这似乎适用于预期的每个 SignalR 调用。虽然到目前为止我在这个设计上没有遇到任何问题,但在阅读了这个问题之后(在 this 文章中),特别是这一行:

在当前方法中,如果请求中有两个 UserManager 实例对同一用户起作用,它们将使用用户对象的两个不同实例。”,我决定问社区:

问题:使用 ASP.NET Identity 的 UserManager 的首选方式是什么?使用 SignalR 类,如果必须我为存储库的方法使用与 UserManager 相同的 DbContext 实例的 UserStore用途?

最佳答案

我认为首选的方法是使用控制反转容器和构造函数注入(inject)具有某种生命周期范围的依赖项。这是您可能想要研究的另一个问题:

Using Simple Injector with SignalR

您的 DbContext 实例最好与当前 Web 请求一样长。 IoC 容器具有允许您在每个 Web 请求生命周期内注册 DbContext 实例的设施,但您需要设置 IoC 容器,以便它可以管理 Hub 类的构造为了达成这个。一些 IoC 容器(如 SimpleInjector)也会在 Web 请求结束时为您自动处理 DbContext,因此您无需在 using 中包装任何内容 block 。

至于 UserManagerXyzRepository 等,我认为它们也可以有每个网络请求的生命周期,甚至是短暂的生命周期。最终,我不明白为什么您无法实现这样的目标:

public class MyXyzHub : Hub
{
private readonly UserManager<ApplicationUser> _userManager;
private readonly MessageRepository _messageRepository;

public MyXyzHub(UserManager<ApplicationUser> userManager,
MessageRepository messageRepository)
{
_userManager = userManager;
_messageRepository= messageRepository;
}

public void sendMessage(string message)
{
var user = _userManager.FindByIdAsync(...
_messageRepository.CreateAndSave(new Message
{
Content = message, UserId = user.Id
});
Clients.All.receiveMessage(message, user.Name);
}
}

如果您以正确的方式连接 IoC 容器,那么每次构建 Hub 时,它都应该为当前的 Web 请求重用相同的 ApplicationDbContext 实例。对于您当前的代码,看起来 XyzRepository 永远不会处理您的 ApplicationDbContext,这是 IoC 容器可以帮助您解决的另一个问题。

关于c# - SignalR 和 ASP.NET Identity 的 UserManager 类生命周期,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27744327/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com