gpt4 book ai didi

c# - 在不完全注入(inject)的情况下访问 DBContext

转载 作者:行者123 更新时间:2023-11-30 12:55:44 25 4
gpt4 key购买 nike

我在使用/通过反射进行整个依赖注入(inject)时遇到了一些麻烦。

场景如下;

  • 用户通过我们的身份服务器通过 AzureAD 进行身份验证
  • 如果用户不在本地数据库中,则将用户与其他一些信息一起保存

我一直在重构我的逻辑,但我仍然无法拼出这个谜题。

目前这是我的链:

OWIN 启动:

我正在指定一个在 OnTokenValidated 事件触发后运行的方法:ProfileEvents.ValidatedToken

services.AddAuthentication()
.AddOpenIdConnect("oidc", o =>
{
o.ClientId = $"{configuration["Globals:AzureApplication:AppId"]}";
o.SignInScheme = IdentityServerConstants.ExternalCookieAuthenticationScheme;
o.Authority = $"https://login.microsoftonline.com/{configuration["Globals:AzureApplication:TenantId"]}";
o.ResponseType = OpenIdConnectResponseType.CodeIdTokenToken;
o.Events = new OpenIdConnectEvents()
{
OnTokenValidated = ProfileEvents.ValidatedToken
};
});

DatabaseContext 是这样添加的:

    public void ConfigureServices(IServiceCollection services)
{
.... // other stuff

services.Configure<Config.ConnectionStrings>(configuration.GetSection("ConnectionStrings"));

services.AddDbContext<ModelContext>(options => options.UseSqlServer(configuration.GetConnectionString("DefaultConnection")));
}

我的 ValidatedToken 方法如下所示:

 internal static class ProfileEvents
{
internal static Task ValidatedToken(TokenValidatedContext context)
{
var dbContext = new ProfileDAL();
dbContext.SaveToDb(context.Principal);
return Task.FromResult(0);
}
}

最后我的 ProfileDAL 看起来像这样:

public class ProfileDAL
{
internal async Task SaveToDb(ClaimsPrincipal principal)
{
var nameClaim = principal.FindFirstValue("http://schemas.xmlsoap.org/ws/2005/05/identity/claims/upn");
var emailClaim = principal.FindFirstValue("email");
// TODO: Save user..
}
}

现在我转向哪个方向,我要么必须使用 IOptions 并通过链传递,以便 ModelContext 可以覆盖“OnConfiguring”以实际获取连接字符串,要么我必须传递上下文。

真的没有办法访问 DI 外部的连接字符串吗?

对我来说,我觉得这样的事情可以解决我当前的所有问题:

  public partial class ModelContext : DbContext
{
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
optionsBuilder.UseSqlServer( ** Magic way to access connection string in appsettings ** );
}
}

最佳答案

当您谈到“沿链向下传递”时,这应该是没有必要的。如果我们使用依赖注入(inject)容器,那么我们不必将依赖传递给一个类,也不必将依赖传递给另一个类,等等。事实上,这是我们使用容器所避免的一部分。

我们不必这样做,因为每个类都将其依赖项作为抽象(通常是接口(interface))接收。这意味着一个类不能将某些东西传递给它的依赖项,因为它甚至不知道该依赖项需要什么。

不是像在链中那样将某些东西从一个类传递到另一个类,而是每个单独的类只根据它需要的依赖关系来解析。链中的任何类都不负责为其依赖项提供构造函数参数。

当我们使用像 ProfileEvents 这样的静态类时,这会变得更加困难。您不能将 ProfileDAL 注入(inject)其中,因为它是静态的。然后,因为 ProfileDAL 没有得到“更新” - new ProfileDAL() - 没有办法注入(inject)它的依赖项。

这反过来意味着您不会对 ProfileDAL 使用构造函数注入(inject),您将寻找其他方法来创建和传递其依赖项。但是使用 DI 容器应该可以防止这种情况发生。在依赖关系图中,一切都遵循相同的模式,其中每个类都在其构造函数中获取其依赖关系,而不知道或不关心那些类具有什么依赖关系。

关于c# - 在不完全注入(inject)的情况下访问 DBContext,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46567280/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com