c# - 如何从 C# 代码正确使用 Scoped 服务
问题描述
我使用 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; }
打印“用户:我”应该只发生一次,因为锁定布尔LoadedStartup被更改,问题是每次注入发生时我都会得到打印(在更改页面等)
我究竟做错了什么?AddScoped() 不是假设为每个客户端添加一个“singelton”实例吗?我是否错误地访问它?
我找不到任何从分离的 .cs 和 .razor 页面中使用 AddScoped 的示例,只能直接从 .razor 页面中找到,然后使用@inject完成。
解决方案
我处于同样的情况:
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/
推荐阅读
- django - 如何基于身份验证对某个 url 使用不同的视图?
- mysql - 无法在 Linux mint 19 中安装 mysql
- r - ggplot2:反转点的顺序,所以小值是大点,大值是小点
- java - Arraylist 检查 CustomerID 是否在 Rent ArrayList
- c++ - 声明一个原子迭代器
- laravel - laravel - 实现遗留 API 调用,包括?参数
- javascript - 制作 1 和 0 的所有组合。代码在 java 中运行良好,但在 js 中运行良好
- semantic-versioning - 如何组合语义版本?
- c# - 如何在 c# 中读取与父节点同名的 xml 节点子节点
- asp.net-core - 通过应用程序设置在 ASP.NET Core Azure Web 应用程序的 web.config 中设置 requestTimeout