【发布时间】:2019-02-28 15:23:39
【问题描述】:
在一个 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 的方法吗?在 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>>()));
【问题讨论】:
标签: asp.net-core dependency-injection