访问DBContext而不将其一直注入

时间:2017-10-04 14:20:15

标签: c# dependency-injection .net-core entity-framework-core

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

方案如下;

  • 用户通过我们的身份服务器通过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 ** );
        }
     }

1 个答案:

答案 0 :(得分:0)

当你谈到“传递链条”时,这不应该是必要的。如果我们使用依赖注入容器,那么我们不必将依赖项传递给一个类,将依赖项传递给另一个类,依此类推。事实上,这是我们通过使用容器避免的一部分。

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

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

当我们使用像ProfileEvents这样的静态类时,这变得更加困难。您无法将ProfileDAL注入其中,因为它是静态的。然后,因为ProfileDAL没有获得&#34;新的&#34; - new ProfileDAL() - 无法注入其依赖项。

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