首页 > 解决方案 > 依赖项未直接注入 .NET Core 中的私有字段

问题描述

在我的appsettings.json文件中,我有如下部分:

"MongoDbSettings": {
   "ConnectionString": "mongodb://localhost:127.0.0.1",
   "DatabaseName": "ComparisonDb"
}

而且,我有一个自定义类,可以处理以上两个子部分。

public interface IMongoDbSetting
{
    string DatabaseName { get; set; }

    string ConnectionString { get; set; }
}

public class MongoDbSetting : IMongoDbSetting
{
    public string DatabaseName { get; set; }

    public string ConnectionString { get; set; }
}

我在我的Startup.cs文件上做了以下定义:

        services.Configure<MongoDbSetting>(Configuration.GetSection("MongoDbSettings"));

        //...

        services.AddSingleton<IMongoDbSetting>(serviceProvider => serviceProvider.GetRequiredService<IOptions<MongoDbSetting>>().Value);

        services.AddControllers();

而且,我有一个 UserRepository 类,它返回由变量提供的正确 DB Provider 的 Repository 类:

    public class UserRepository : IUserRepository<User>
    {
        private SqlServerDbContext _dbContext;
        private IMongoDbSetting mongoDbSetting; //DI doesn't fill this up

        public IOperation<User> GetRepository(DbType dbType)
        {
            if (dbType == DbType.SqlServer)
            {
                if (_dbContext == null)
                {
                    _dbContext = new SqlServerDbContext();
                }

                return new DbFactory<SqlServerDbContext, User>(_dbContext).GetDb(dbType);
            }
            else if (dbType == DbType.MongoDB)
            {
                return new DbFactory<SqlServerDbContext, User>(mongoDbSetting).GetDb(dbType);
            }
            else
            {
                throw new NotImplementedException("Undefined DB provider");
            }
        }
    }

IMongoDbSetting尽管我在启动文件中有定义,但这里始终为空。我需要将我的MongoDbSetting类传递给DbFactory最终MongoDbRepositoryBase在其构造函数中需要此文件。下面,您可以看到其他两个类。

数据库工厂:

    public class DbFactory<C, T> where C : BaseDataContext where T : class
    {
        public C _baseDataContext;
        public IMongoDbSetting _mongoDbSetting;

        public DbFactory(IMongoDbSetting mongoDbSetting)
        {
            _mongoDbSetting = mongoDbSetting;
        }

        public DbFactory(C baseDataContext)
        {
            _baseDataContext = baseDataContext;
        }

        public IOperation<T> GetDb(DbType dbType)
        {
            switch (dbType)
            {
                case DbType.SqlServer:
                    return new SqlServerRepositoryBase<C, T>(_baseDataContext);
                case DbType.MongoDB:
                    return new MongoDbRepositoryBase<T>(_mongoDbSetting);
                default:
                    throw new ArgumentOutOfRangeException(nameof(dbType), "Undefined DB provider");
            }
        }
    }

MongoDbRepositoryBase:

    public class MongoDbRepositoryBase<T> : IOperation<T> where T : class
    {
        private readonly IMongoCollection<T> _collection;

        public MongoDbRepositoryBase(IMongoDbSetting settings)
        {
            IMongoDatabase database = new MongoClient(settings.ConnectionString).GetDatabase(settings.DatabaseName);

            _collection = database.GetCollection<T>(GetCollectionName(typeof(T)));
        }

       //CRUD methods
    }

标签: .net-coredependency-injection

解决方案


据我所知,ASP.NET Core 的 DI 仅支持构造函数注入。所以你需要类似的东西

public UserRepository(IMongoDbSetting mongoDbSetting, ...) {
    _mongoDbSetting = mongoDbSetting;
    // and so on
}

让 DI 注入你想要的东西。

或者(我个人不会走这条路,但这是一个选择)你可以让你的代码ServiceProvider直接要求提供一个实例,这里有一个例子

作为旁注,您的_mongoDbSettings字段也是private. 我相信可以进行字段注入的 DI 框架至少需要对其进行保护。可能是错误的,但这是未来要记住的事情。


推荐阅读