В приложении asp.net core 2.1 MVC у меня есть следующий код, полученный из Github из слепка, и некоторые дополнения, сделанные мной:
public static IServiceCollection AddIdentityMongoDbProvider<TUser, TRole>(this IServiceCollection services, Action<IdentityOptions> setupIdentityAction, Action<MongoIdentityOptions> setupDatabaseAction) where TUser : UserEntity where TRole : RoleEntity
{
services.AddIdentity<TUser, TRole>(setupIdentityAction ?? (x => { }))
.AddRoleStore<RoleStore<TRole>>()
.AddUserStore<UserStore<TUser, TRole>>()
.AddDefaultTokenProviders();
var dbOptions = new MongoIdentityOptions();
setupDatabaseAction(dbOptions);
var userCollection = new IdentityUserCollection<TUser>(dbOptions.DbType, dbOptions.ConnectionString);
var roleCollection = new IdentityRoleCollection<TRole>(dbOptions.DbType, dbOptions.ConnectionString);
// Add collections and stores in services for DI
services.AddTransient<IIdentityUserCollection<TUser>>(x => userCollection);
services.AddTransient<IIdentityRoleCollection<TRole>>(x => roleCollection);
services.AddTransient<ITenantStore<TenantEntity, TUser>>(x => new TenantStore<TenantEntity, TUser>(dbOptions.DbType, dbOptions.ConnectionString, userCollection));
services.AddTransient<ILicenseStore<LicenseEntity>>(x => new LicenseStore<LicenseEntity>(dbOptions.DbType, dbOptions.ConnectionString));
// Identity Services
services.AddTransient((Func<IServiceProvider, IUserStore<TUser>>)(x => new UserStore<TUser, TRole>(userCollection, roleCollection, x.GetService<ILookupNormalizer>())));
services.AddTransient<IRoleStore<TRole>>(x => new RoleStore<TRole>(roleCollection));
return services;
}
Итак, как вы можете видеть, он используетвнедрение зависимости, но я задаю себе несколько вопросов:
1) userCollection и roleCollection являются «локальной» переменной, которая затем передается в DI.Но тогда как управляется жизненный цикл этих объектов?Я имею в виду, они никогда не избавляются, потому что они используются в DI?Или они создают каждый раз?
2) Есть ли разница между
services.AddTransient<ILicenseStore<LicenseEntity>>(x => new LicenseStore<LicenseEntity>(dbOptions.DbType, dbOptions.ConnectionString));
и
services.AddTransient<ILicenseStore<LicenseEntity>>(new LicenseStore<LicenseEntity>(dbOptions.DbType, dbOptions.ConnectionString));
3) В строке
services.AddTransient((Func<IServiceProvider, IUserStore<TUser>>)(x => new UserStore<TUser, TRole>(userCollection, roleCollection, x.GetService<ILookupNormalizer>())));
Существует функция x.GetService ().Это способ сказать конструктору, что параметр, необходимый в конструкторе, будет из DI?Что-то вроде использования Dependency Injection в DependecyInjection?
4) В случае положительного ответа на вопрос 3, возможно ли сделать что-то подобное?
services.AddSingletion<IMongoClient>(new MongoClient("connectionString"));
services.AddTransient<IXStore>(new XStore(x.GetService<IMongoClient>()))
Смысл в том, чтобы добиться того, что MongoClientбудет синглтон (что является рекомендуемым способом)
5) В чем разница между:
services.AddScoped((Func<IServiceProvider, IUserStore<TUser>>)(x => new UserStore<TUser, TRole>(x.GetRequiredService<IIdentityUserCollection<TUser>>(), x.GetRequiredService<IIdentityRoleCollection<TRole>>(), x.GetService<ILookupNormalizer>())));
и
services.AddScoped<IUserStore<TUser>, UserStore<TUser, TRole>>();
Большое спасибо за ответы:)
Редактировать:
Новый способ:
services.AddSingleton<ICustomMongoClient>(x => new CustomMongoClient(dbOptions.ConnectionString));
// Add collections and stores in services for DI
services.AddTransient<IIdentityUserCollection<TUser>>(x => new IdentityUserCollection<TUser>(x.GetRequiredService<ICustomMongoClient>()));
services.AddTransient<IIdentityRoleCollection<TRole>>(x => new IdentityRoleCollection<TRole>(x.GetRequiredService<ICustomMongoClient>()));
services.AddTransient<ITenantStore<TenantEntity, TUser>>(x => new TenantStore<TenantEntity, TUser>(x.GetRequiredService<ICustomMongoClient>(), x.GetRequiredService<IIdentityUserCollection<TUser>>()));
services.AddTransient<ILicenseStore<LicenseEntity>>(x => new LicenseStore<LicenseEntity>(x.GetRequiredService<ICustomMongoClient>()));
// Identity Services
services.AddTransient((Func<IServiceProvider, IUserStore<TUser>>)(x => new UserStore<TUser, TRole>(x.GetRequiredService<IIdentityUserCollection<TUser>>(), x.GetRequiredService<IIdentityRoleCollection<TRole>>(), x.GetService<ILookupNormalizer>())));
services.AddTransient<IRoleStore<TRole>>(x => new RoleStore<TRole>(x.GetRequiredService<IIdentityRoleCollection<TRole>>()));