简体   繁体   English

如何从 C# 代码正确使用 Scoped 服务

[英]how to properly use Scoped service from c# code

im using blazor server side and are therefore trying to use AddScoped instead of AddSingleton as the object is used on a per-user basis.我使用 blazor 服务器端,因此尝试使用 AddScoped 而不是 AddSingleton,因为该对象是基于每个用户使用的。 I try to split the razor pages and the c# code as much as posible as i find this to be cleaner.我尝试尽可能多地拆分剃刀页面和 c# 代码,因为我发现这更干净。

I add a scoped service using我使用添加范围服务

Services.AddScoped<Services.ManageUserService>();

in the ConfigureServices function of the Startup class.在 Startup 类的 ConfigureServices 函数中。

my problem now is to properly access the service from any .cs file (holding the logic of my .razor pages)我现在的问题是从任何 .cs 文件正确访问服务(保存我的 .razor 页面的逻辑)

I have tried to do an injection like this:我试图做这样的注射:

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

and then accesed the scoped object using (username for example):然后使用(例如用户名)访问范围对象:

manageUserService.User

and this works.这有效。 My problem is that if I add a print that is supose to only run once within the scoped service it runs every time the page is reloaded or changed.我的问题是,如果我添加一个只在范围服务中运行一次的打印,它会在每次重新加载或更改页面时运行。

for example, lets say i do this:例如,假设我这样做:

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);
        }
    }
}

I then access the class from multiply .cs files using:然后我使用以下方法从多个 .cs 文件中访问该类:

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

The print "User:me" is supposed to only happen once as the locking bool LoadedStartup is changed, problem is that I get the print every time the Inject is happening (on change page, etc)打印“用户:我”应该只在锁定 bool LoadedStartup更改时发生一次,问题是每次发生注入时我都会得到打印(在更改页面等)

What am I doing wrong?我究竟做错了什么? aren't the AddScoped() suppose to add a "singelton" instance for every client? AddScoped() 不是假设为每个客户端添加一个“singelton”实例吗? am I accessing it wrongly?我是否错误地访问了它?

I can't find any examples of using AddScoped from separated .cs and .razor pages, only directly from the .razor page, and then it is done using @inject .我无法从单独的 .cs 和 .razor 页面中找到任何使用 AddScoped 的示例,只能直接从 .razor 页面中找到,然后使用@inject完成。

I was in the same situation:我处于同样的情况:

1.- Add the scoped services: 1.- 添加范围服务:

Services.AddScoped<Services.ManageUserService>();

2.- Then, in order to have really the scoped instances once per user, in _Hosts.cshtml: 2.- 然后,为了每个用户拥有一次真正的范围实例,在 _Hosts.cshtml 中:

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

3.- Now the trick I found by myself, instance the scoped services in App.razor 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.- And if you have in the constructor something like: 4.- 如果你在构造函数中有类似的东西:

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

}

You can access to any class you define as service from anywhere in your code.您可以从代码中的任何位置访问您定义为服务的任何类。

 MainViewModel.Instance...

I post about it at my blog: https://expediteapps.net/2020/02/18/scoped-viewmodels-instanced-once-on-start/我在我的博客上发布了它: https : //expediteapps.net/2020/02/18/scoped-viewmodels-instanced-once-on-start/

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM