Как создать и внедрить специфичный для пользователя одноэлементный класс во все приложение?

Я пытаюсь создать одноэлементный объект для конкретного пользователя в серверном приложении Blazor. Есть ли способ добиться этого с помощью системы внедрения зависимостей .NET Core? Я пробовал код ниже. Я создал класс SingletonTest.

public class SingletonTest
{
    private int _counter;
    public int Counter { get { return ++_counter; } }
}

Внедрил класс SingletonTest в Startup.cs

public void ConfigureServices(IServiceCollection services)
{
    services.AddSingleton<SingletonTest>();
}

Доступ к свойству Counter в файле index.razor

@page "/"
@inject SingletonTest singletonTest;
Counter: @singletonTest.Counter

Когда я пытаюсь получить доступ к странице индекса в двух разных браузерах, оба обращаются к одному и тому же единственному экземпляру класса SingletonTest. Есть ли способ сделать этот синглтон для конкретного пользователя? после закрытия браузера серверу необходимо удалить пользовательский одноэлементный объект и вызвать сборщик мусора.


person Dragon Warrior    schedule 07.06.2020    source источник
comment
Что, если бы ваш синглтон хранил словарь, введенный пользователем, а не одно значение? Кроме того, не ожидайте, что ++ будет потокобезопасным.   -  person mjwills    schedule 07.06.2020
comment
Планируете ли вы ограничить количество пользователей, которые могут использовать приложение, или периодически перезапускать пул приложений? Это в лучшем случае сомнительный дизайн.   -  person 3Dave    schedule 07.06.2020
comment
Для этого и нужны базы данных.   -  person 3Dave    schedule 07.06.2020
comment
@ 3Dave нет ограничений для пользователей и не будет перезапускать пул приложений. После закрытия браузера серверу необходимо удалить созданный пользователем объект.   -  person Dragon Warrior    schedule 07.06.2020
comment
@mjwills есть ли способ обнаружить пользователя, добавить его в словарь и удалить после закрытия браузера (после отключения сигнализатора)?   -  person Dragon Warrior    schedule 07.06.2020


Ответы (1)


Добавить Scoped - это то, что вам нужно, если вы хотите, чтобы он был доступен только для одного экземпляра браузера:

services.AddScoped<YourScopedClass>();

Еще вы можете использовать предварительный просмотр пакета Nuget:

Microsoft.AspNetCore.ProtectedBrowserStorage

документы для ProtectedBrowserStorage на этой странице примерно на 40% ниже: https://docs.microsoft.com/en-us/aspnet/core/blazor/state-management?view=aspnetcore-3.1

Я использую вышеупомянутый пакет здесь, в проекте Blazor на стороне сервера под названием BlazorChat, который использует одноэлемент, точно так же, как вы должны общаться со всеми пользователями, но ProtectedBrowserStorage для хранения хэша пароля пользователей, адреса электронной почты и имени входа.

https://github.com/DataJuggler/BlazorChat

Сайт тоже работает, но пока никто, кроме меня, не подписался.

https://blazorchat.com

введите здесь описание изображения

person Community    schedule 07.06.2020
comment
AddScoped не будет работать, если просто обновить. Он просто воссоздает новый объект. - person Dragon Warrior; 08.06.2020