代码之家  ›  专栏  ›  技术社区  ›  hkjhadj1

在配置服务后添加标识

  •  1
  • hkjhadj1  · 技术社区  · 6 年前

    我正在尝试在 ConfigureServices 方法。因为我已经注册了 dbContext 配置服务 方法。所以,现在我必须在配置之后配置标识 数据库上下文 (再说一遍,我在 配置服务 ). 我所做的一切 数据库上下文 是我创建了一个工厂并将其添加到 配置服务 :

    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操作,但是,标识不起作用,它引发并异常:

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

    那是因为我在 配置服务 不设置 数据库上下文 首先(因为它是在 配置服务 方法。

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

    有没有一种方法可以像我设置dbContext那样设置identity?

    编辑: DbContextFactory 包括 Create 返回 AppDbContext . 它从一些配置文件中读取用户对数据库提供程序的选择,相应地注册该提供程序,然后返回 AppDbContext . 这是 创建 方法:

    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 . 这就是本节的内容:

    "DatabaseProvider": "MSSQL", //could be MySQL, SQLite etc etc
    "ConnectionStrings": {
    "MSSQL": "Server=(localdb)\\MSSQLLocalDB;Database=XXX_db;Trusted_Connection=True;MultipleActiveResultSets=true",
    "SQLite": "Data Source=XXX_db.db"
     }
    
    1 回复  |  直到 6 年前
        1
  •  0
  •   Nkosi    6 年前

    像往常一样在 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>()));