как правильно использовать сервис Scoped из c# кода - PullRequest
0 голосов
/ 11 марта 2020

Я использую сервер Blazor и поэтому пытаюсь использовать AddScoped вместо AddSingleton, поскольку объект используется для каждого пользователя. Я пытаюсь разделить бритвенные страницы и код c# настолько, насколько это возможно, так как я считаю, что это чище.

Я добавляю сервис с областью действия, используя

Services.AddScoped<Services.ManageUserService>();

в функции ConfigureServices класса Startup.

Теперь моя проблема заключается в правильном доступе к службе из любого файла .cs (содержащего logi c моих страниц .razor)

Я попытался сделать Внедрение выглядит следующим образом:

[Inject]
public Services.ManageUserService manageUserService { get; set; }

, а затем принимает объект области действия, используя (имя пользователя, например):

manageUserService.User

, и это работает. Моя проблема заключается в том, что если я добавлю распечатку, которая может быть запущена только один раз, в сервисе с заданной областью, он запускается каждый раз, когда страница перезагружается или изменяется. Например,

, допустим, я делаю это:

public class ManageUserService
{
    public string User { get; private set; }

    private bool LoadedStartup = false;

    public ManageUserService() => SetupUser();

    private void SetupUser()
    {
        if (!LoadedStartup)
        {
            User = "me";
            LoadedStartup = true;
            System.Diagnostics.Debug.Print("User:" + User);
        }
    }
}

Затем я получаю доступ к классу из нескольких файлов .cs, используя:

[Inject]
public Services.ManageUserService manageUserService { get; set; }

Печать "Пользователь: я" должна происходить только один раз как блокировка bool LoadedStartup изменено, проблема в том, что я получаю распечатку каждый раз, когда происходит инъекция (на странице изменений и т. Д. c)

Что я делаю неправильно? разве AddScoped () не предполагает добавить экземпляр "singelton" для каждого клиента? я получаю к нему неправильный доступ?

Я не могу найти примеров использования AddScoped с отдельных страниц .cs и .razor, только непосредственно со страницы .razor, а затем это делается с помощью @ inject .

1 Ответ

1 голос
/ 11 марта 2020

Я был в такой же ситуации:

1.- Добавьте сервисы с областью действия:

Services.AddScoped<Services.ManageUserService>();

2.- Затем, чтобы действительно иметь экземпляры с областью действия один раз на пользователя, в _Hosts.cs html:

<app>
 <component type="typeof(App)" render-mode="Server" />
</app>

3.- Теперь уловка, которую я нашел сам, например, определение служб в App.razor

@inject Examples.ViewModels.MainViewModel Main;
@inject Examples.ViewModels.ChildViewModel Child;
@inject Examples.ViewModels.LayoutViewModel Layout;
@inject Examples.ViewModels.TreeViewModel Tree;
@{

Child.Main = Main;
Tree.LayoutViewModel = Layout;
}

4.- И если у вас есть в конструкторе что-то вроде:

public class MainViewModel
{
  public static MainViewModel Instance;
  public MainViewModel()
  {
  Instance = this;
 }

}

Вы можете получить доступ к любому классу, который вы определили как сервис, из любой точки вашего кода.

 MainViewModel.Instance...

Я публикую об этом в своем блоге: https://expediteapps.net/2020/02/18/scoped-viewmodels-instanced-once-on-start/

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...