asp.net核心2.1依赖注入

内容来源于 Stack Overflow,并遵循CC BY-SA 3.0许可协议进行翻译与使用

  • 回答 (1)
  • 关注 (0)
  • 查看 (35)

在一个asp.net核心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是'local'变量,然后传递给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将是一个单例(这是推荐的方式)

非常感谢你的答案:)

提问于
用户回答回答于

首先,userCollection和roleCollection仅实例化一次。由于以下原因,这两个局部变量都不会被垃圾收集。它们由使用lambdas创建的委托(x => userCollection和x => roleCollection)捕获,并且委托被添加到服务集合中,这绝对是GC根目录。

就在这里。第一行编译而后一编编没有。您只能将构造对象传递给AddSingleton。 services.AddSingleton(x => new object)和services.AddSingleton(new object)之间的唯一区别是对象实例化时,现在(新对象)或第一次请求指定的服务类型(x => new object) )。

是。如果你修复第二行

services.AddSingletion <IMongoClient>(new MongoClient(“connectionString”)); services.AddTransient <IXStore>(x => new XStore(x.GetService <IMongoClient>()))

然后回答是的。实际上,DI容器为您执行此操作,为每个构造函数参数调用GetService。所以下面的代码等同于你的代码

services.AddSingletion <IMongoClient>(new MongoClient(“connectionString”)); services.AddTransient <IXStore,XStore>()

扫码关注云+社区

领取腾讯云代金券