【问题标题】:how to properly use Scoped service from c# code如何从 c# 代码正确使用 Scoped 服务
【发布时间】:2020-03-11 12:09:24
【问题描述】:

我使用 blazor 服务器端,因此尝试使用 AddScoped 而不是 AddSingleton,因为该对象是按用户使用的。我尝试尽可能多地拆分剃须刀页面和 c# 代码,因为我觉得这样更干净。

我使用

添加范围服务
Services.AddScoped<Services.ManageUserService>();

在 Startup 类的 ConfigureServices 函数中。

我现在的问题是从任何 .cs 文件(保存我的 .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; }

打印 "User:me" 应该只发生一次,因为锁定布尔 LoadedStartup 已更改,问题是每次 Inject 时我都会打印发生(在更改页面等)

我做错了什么? AddScoped() 不是假设为每个客户端添加一个“singelton”实例吗?我是不是访问错了?

我找不到任何从单独的 .cs 和 .razor 页面中使用 AddScoped 的示例,只能直接从 .razor 页面中找到,然后使用 @inject 完成。

【问题讨论】:

    标签: c# razor server-side blazor inject


    【解决方案1】:

    我也遇到过这种情况:

    1.- 添加作用域服务:

    Services.AddScoped<Services.ManageUserService>();
    

    2.- 然后,为了让每个用户真正拥有一次作用域实例,在 _Hosts.cshtml 中:

    <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/

    【讨论】:

    • 对于一个让我发疯的问题,这是一个很好的答案(而且 rly 应该很容易解决),如果它有效,我会尝试并接受它!谢谢!
    猜你喜欢
    • 1970-01-01
    • 2019-08-02
    • 2019-07-21
    • 1970-01-01
    • 2013-12-03
    • 1970-01-01
    • 2016-02-03
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多