- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
我已经创建了一个接口(interface)
public interface ICurrentUser
{
Task<bool> Set(UserAuth user);
User Get();
}
和一个类
public class CurrentUserSvc : Interface.ICurrentUser
{
private User _u;
private UserAuth _ua;
private AppDbContext db;
public CurrentUserSvc(AppDbContext db) {
this.db = db;
}
public User Get()
{
return _u;
}
public async Task<bool> Set(UserAuth ua)
{
_ua = ua; // this is the default EntityFramework IdentityUser
_u = await db.AppUsers // this is my applicaiton's 'extra settings'
// user used to ensure passowrd fields are
// not passed about everywhere
.Where(u => u.UserID == _ua.UserID)
.SingleAsync();
return true;
}
}
在我设置的Startup.cs
中
services.AddScoped<ICurrentUser, CurrentUserSvc>();
// I also add a service which will be used later in a scoped
// lifecycle (though I've also tried transient on that one)
services.AddScoped<IProductDbSvc, ProductDbSvc>();
稍后我调用了一个中间件:
public async Task<Task> Invoke(HttpContext hc)
{
if (hc.User.Identity.IsAuthenticated) {
UserAuth iu = await _um.FindByIdAsync(hc.User.GetUserId());
await _cus.Set(iu);
}
// the values are definitely set correctly here.
// I have inspected them during debug
return _next(hc);
}
稍后我仍然尝试访问 CurrentUserSvc
的内容 我尝试通过 GET 访问当前用户
public ProductDbSvc(AppDbContext db, ICurrentUser cu){
this.db = db;
this.cu = cu;
// the values in cu are NULL here. Get() returns null
this.CurrentUser = cu.Get();
}
但是 Get() 的结果是 null
我期望 Scoped 参数会保留在请求生命周期中较早设置的值。
我错过了什么?是否有其他方法可以确保作用域单例在整个应用程序的生命周期中保留用户数据。
更新:我创建了一个通用项目来概括说明这个问题。 https://github.com/AlexChesser/AspnetIdentitySample
您会注意到,在 DEBUG 输出中,您可以看到设置了正确的用户详细信息,但在实际 Controller 本身中,返回的值为空。
UPDATE 2 工作示例在 github https://github.com/AlexChesser/AspnetIdentitySample/tree/dependencyinjectionscoped 的这个分支上
UPDATE 3 结果表明,作用域参数也可以注入(inject)到自定义中间件的 INVOKE 方法中。 https://github.com/AlexChesser/AspnetIdentitySample/commit/25b010a5ae45678c137b2ad05c53ccd659a29101 更改调用方法将允许正确注入(inject)作用域参数。
public async Task Invoke(HttpContext httpContext,
ICurrentUserService cus,
UserManager<ApplicationUser> um)
{
if (httpContext.User.Identity.IsAuthenticated)
{
ApplicationUser au = await um.FindByIdAsync(httpContext.User.GetUserId());
await cus.Set(au);
}
await _next(httpContext);
}
更新 4 - 昨晚我发现我的中间件签名存在一个非常重要的问题。上面的代码已被编辑为正确的形式。具体方法是 Task<Task>
和 return _next(...)
这导致某些页面加载时出现“白屏”死机(异步调用错误不会抛出堆栈跟踪)
通过更改为 Task
并使用 await next(...)
,代码可以正常运行并消除因 dotnet5 中异步实现不当而导致的间歇性白屏死机。
最佳答案
DbContext
是范围服务,您的 CurrentUserSvc
也是范围服务。中间件在应用程序的整个运行时间内只被实例化一次,所以它们本质上是单例的。因此,您需要将 DbContext
和 CurrentUserSvc
都从此处注入(inject)的构造函数中移除。
相反,您可以使用 HttpContext
的 RequestServices
属性(它返回一个 IServiceProvider
)来解析 DbContext
和 CurrentUserSvc
服务。
关于c# - AddScoped 服务不会在整个请求中保留设置,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34388790/
我已经创建了一个接口(interface) public interface ICurrentUser { Task Set(UserAuth user); User Get(); }
我正在尝试同时学习 asp.net core (3.1) 和 clean architecture。我用作基础的 GitHub 存储库是 https://github.com/ivanpaulovic
为什么我应该为我的存储库或服务使用 AddScoped()?为什么不是 AddSingleton()?我知道它们之间的区别,但不明白为什么我不应该使用单例实例来避免为每个请求创建新对象。你能解释一下吗
为什么我应该为我的存储库或服务使用 AddScoped()?为什么不是 AddSingleton()?我知道它们之间的区别,但不明白为什么我不应该使用单例实例来避免为每个请求创建新对象。你能解释一下吗
在 IServiceCollection 上,提供的注册服务 AddTransiet、AddScoped、AddSingleton 的方法不允许您在必须通过计算其某些步骤来检索服务时使用 async-
我想实现 dependency injection ASP.NET Core 中的 (DI)。因此,将此代码添加到 ConfigureServices 方法后,两种方式都有效。 ASP.NET Cor
在 asp.net 核心应用程序中,我有一个依赖注入(inject)缓存服务,它本质上是内置 MemoryCache 的包装器。 这是被缓存的示例类,它包含 Web 应用程序始终使用的一些枚举的列表:
假设我想在将作为 Azure Web 作业运行的控制台应用程序中使用依赖注入(inject)。这样做我正在重用我在相关的 Asp.net 应用程序上使用的名为“AddATonOfServices()”
我试图了解 AddSingleton、AddScoped 和 AddTransient 之间的区别。有很多解释,但我看不懂,因为我不明白什么时候HTTP请求在同一个范围内 最佳答案 因此,在 AppD
长话短说 在 .NET 6 中: 类型化的生命周期是多少 HttpClient来自 IHttpClientFactory 的实例将接收它的类型在哪里注册为“Scoped”? 当我们像下面的摘录那样注册
假设我想实现不同的 DbContext(MySql、MsSql),但让应用程序完全不知道它。 因此,使用“AddScoped”(或任何其他)方法,我可以注册以下内容: 或者甚至将它们隐藏在工厂后面
在以下代码中(来自 https://github.com/JasonGT/NorthwindTraders/blob/master/Src/WebUI/Controllers/BaseControll
我一直在使用 asp.net 核心依赖注入(inject),我看到了一个意想不到的行为,至少对我来说是这样。我正在向容器中添加一个新服务,如下所示: services.AddScoped(provid
我想将一个值从请求的 header 分配给每个请求作为单例的类实例。 我想在 ConfigureServices 中用 .net core 分配它Startup 中的方法类(class)。 像这样的东
我的项目中有一个通用存储库。考虑以下 Controller 片段 public class Lookup1Controller : Controller { readonly MyDbCont
我正在使用 StackExchange.Redis 添加到 .NET Core 的 Redis 连接,它目前看起来像这样: public static IServiceCollection AddRe
我是一名优秀的程序员,十分优秀!