每个用户的netcore依赖注入

时间:2016-11-28 14:24:56

标签: dependency-injection asp.net-core

我想知道如何为每个用户设置一个mvc的netcore依赖容器。

根据https://docs.microsoft.com/en-us/aspnet/core/fundamentals/dependency-injection#service-lifetimes-and-registration-options,目前只有三种指定生命周期的方法:singleton(每个应用程序一个实例),scoped(在HttpRequest中共享一个实例),transient(每个DI实例请求一个实例)

有人试图在每个用户的实例上创建吗?我很好奇它是如何完成的 - 如果不是,我可能会在某些时候深入研究文档,看看它是如何完成的并分享解决方案。

3 个答案:

答案 0 :(得分:1)

在第一个用户请求上创建实例并保持活动(对于下一个请求),直到有一些到期超时...这看起来像Sessions

您可以使用工厂方法注册您的服务并分析当前的会话。

答案 1 :(得分:1)

如果这是asp.net核心应用程序,则自动添加到中间件管道中的中间件将处理在请求开始时创建新的DI作用域,并在请求结束时处置该范围。此范围存储在HttpContext中。注入MVC​​控制器等时将使用此范围。因此,如果要将按用户服务注入到MVC控制器/操作方法中,则需要用自己为当前用户构建的HttpContext替换此范围。您必须使用中间件来执行此操作,该中间件必须在身份验证中间件之后运行(因此在建立当前用户之后)。您的自定义中间件将查看当前已通过身份验证的用户,并将GetOrCreate IServiceProvider(容器)保存在某些缓存中,并且可能会过期。有了每个用户的IServiceProvider,它将为当前请求创建一个范围,并使用该用户特定的范围替换HttpContext中当前的范围,并确保在请求结束时将其丢弃。事实是,在构建每个用户容器时,如果为每个用户创建一个新的ServiceCollection并注册一些服务并为该用户构建和缓存该IServiceProvider,则您将无法解析仅拥有的任何服务。在应用程序级别注册,即在启动时注册。子容器的概念在这里很方便,Microsoft并没有立即实现它,但是如果您切换到使用其他DI提供程序(例如Autofac),则可以使用。 Autofac提供IServiceProvider的实现以及生成子容器的功能。如果使用此机制,则可以为每个用户创建一个子容器,这意味着它仍然能够解析所有更高级别的服务,但是现在您还可以解析特定于用户的服务。如果执行所有这些操作,则可以注入每个用户的服务。

这是很多工作。如果有足够的兴趣,我会考虑将此功能添加到我的多租户库中,因为它已经做了类似于创建每个租户容器的操作:https://github.com/dazinator/Dotnettency

答案 2 :(得分:0)

类似的东西?

    var shoppingLists = new Dictionary < string,
ShoppingListStateContainer > ();

services.AddTransient < ShoppingListStateContainer > (s = >{
    var userName = s.GetRequiredService < AuthenticationStateProvider > ().GetAuthenticationStateAsync().GetAwaiter().GetResult().User.Identity.Name ? ?"null";
    lock(s) {
        if (!shoppingLists.ContainsKey(userName)) shoppingLists.Add(userName, new ShoppingListStateContainer());
    }
    return shoppingLists[userName];
});