我正在尝试在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;
}
中读取providerType
和connectionString
。这是本节的样子:
appsettings.json
答案 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>()));