在ConfigureServices之后添加身份

时间:2018-07-30 12:33:32

标签: c# asp.net-core asp.net-identity asp.net-core-2.0

我正在尝试在ConfigureServices方法之后添加身份。这是因为我已经在dbContext方法之外注册了ConfigureServices。因此,现在我必须在配置dbContext之后再配置身份(同样,我已经在ConfigureServices之外完成了此工作)。我为dbContext做的是,我创建了一个工厂并将其添加到ConfigureServices

services.AddScoped<IDbContextFactory, DbContextFactory>();

然后我使用DI将其注入到控制器的构造函数中:

    private IDbContextFactory contextFactory;
    private AppDbContext context;

    public DbTestController(IDbContextFactory _contextFactory)
    {
        contextFactory = _contextFactory;
        context = contextFactory.Create(); //Create() returns an `AppDbContext`
    }

我可以在数据库上执行CRUD操作,但是,Identity无法正常工作,它会抛出异常:

No service for type Microsoft.AspNetCore.Identity.XXX has been registered

这是因为我在ConfigureServices中注册身份,而没有先设置dbContext(因为它是在ConfigureServices方法之后设置的。

services.AddIdentity<IdentityUser, IdentityRole>()
        .AddEntityFrameworkStores<AppDbContext>()
        .AddDefaultTokenProviders();

是否可以使用与设置dbContext相同的方式来设置身份?

编辑:DbContextFactory包含一个返回Create的{​​{1}}方法。它从一些配置文件中读取用户对数据库提供程序的选择,相应地注册提供程序,然后返回AppDbContext。这是AppDbContext方法的代码:

Create

此方法从public AppDbContext Create() { //Get this value from some configuration string providerType = _configuration.GetValue<string>("DatabaseProvider"); //and the connection string for the database string connectionString = _configuration.GetConnectionString(providerType); var dbContextBuilder = new DbContextOptionsBuilder(); //Add some if else blocks here to check which provider to use //and then call dbContextBuilder.UseABC(connectionString) if (providerType == "MSSQL") dbContextBuilder.UseSqlServer(connectionString); else if (providerType == "SQLite") dbContextBuilder.UseSqlite(connectionString); //Create the context context = new AppDbContext(dbContextBuilder); return context; } 中读取providerTypeconnectionString。这是本节的样子:

appsettings.json

1 个答案:

答案 0 :(得分:0)

像往常一样在ConfigureServices中注册上下文和标识,并在启动时在组合根中应用所需的逻辑。

//Get this value from some configuration
string providerType = Configuration.GetValue<string>("DatabaseProvider");

//and the connection string for the database
string connectionString = Configuration.GetConnectionString(providerType);

services.AddDbContext<AppDbContext>(options => {
    if (providerType == "MSSQL")
        options.UseSqlServer(connectionString);
    else if (providerType == "SQLite")
        options.UseSqlite(connectionString);
});

services.AddIdentity<IdentityUser, IdentityRole>()
        .AddEntityFrameworkStores<AppDbContext>()
        .AddDefaultTokenProviders();

您需要做的是重新设计工厂

public class DbContextFactory : IDbContextFactory {

    private readonly Func<AppDbContext> factory;

    public DbContextFactory(Func<AppDbContext> factory) {
        this.factory = factory;
    }

    public AppDbContext Create() {
        return factory();
    }
}

并相应地向工厂代表进行注册

services.AddScoped<IDbContextFactory, DbContextFactory>(sp => 
    new DbContextFactory(() => sp.GetRequiredService<AppDbContext>()));