如何通过依赖注入动态添加LiteDB嵌入式数据库?
最优解决方案:采用数据库工厂模式
针对你遇到的运行时动态创建项目数据库的需求,最稳妥且符合DI设计原则的方案是引入工厂类管理LiteDB实例,既保留依赖注入的可测试性,又能灵活处理动态创建的项目数据库。
1. 定义工厂接口
先抽象工厂行为,方便后续测试时替换为Mock实现:
public interface ILiteDbFactory { // 根据项目路径获取/创建对应的LiteDB实例 ILiteDatabase GetDatabase(string projectPath); // 关闭项目时释放对应数据库连接 void ReleaseDatabase(string projectPath); }
2. 实现工厂类
内部用字典缓存已创建的数据库实例,避免重复初始化:
public class LiteDbFactory : ILiteDbFactory { private readonly Dictionary<string, ILiteDatabase> _dbCache = new(); private readonly object _lock = new(); public ILiteDatabase GetDatabase(string projectPath) { lock (_lock) { if (_dbCache.TryGetValue(projectPath, out var existingDb)) { return existingDb; } // 生成项目对应的数据库文件路径(可根据需求调整命名规则) var dbFilePath = Path.Combine(projectPath, $"{Path.GetFileName(projectPath)}.db"); var newDb = new LiteDatabase(dbFilePath); _dbCache.Add(projectPath, newDb); return newDb; } } public void ReleaseDatabase(string projectPath) { lock (_lock) { if (_dbCache.TryRemove(projectPath, out var db)) { db.Dispose(); } } } }
3. 注册工厂到DI容器
在应用启动时,将工厂注册为单例:
serviceCollection.AddSingleton<ILiteDbFactory, LiteDbFactory>();
4. 修改持久化服务
注入工厂而非直接注入单个数据库实例,使用时通过项目路径获取对应的数据库:
public class PersistenceService { private readonly ILiteDbFactory _dbFactory; private string _activeProjectPath; public PersistenceService(ILiteDbFactory dbFactory) { _dbFactory = dbFactory; } // 切换当前操作的项目 public void SetActiveProject(string projectPath) { _activeProjectPath = projectPath ?? throw new ArgumentNullException(nameof(projectPath)); } // 示例:获取数据集合的方法 public ILiteCollection<T> GetCollection<T>() where T : new() { if (string.IsNullOrEmpty(_activeProjectPath)) { throw new InvalidOperationException("请先指定当前操作的项目"); } var db = _dbFactory.GetDatabase(_activeProjectPath); return db.GetCollection<T>(); } }
关键优势
- 可测试性:测试时可以实现Mock版
ILiteDbFactory,返回内存型LiteDB(new LiteDatabase(":memory:")),无需依赖真实文件系统。 - 资源可控:用户关闭项目时调用
ReleaseDatabase,及时释放数据库连接,避免资源泄漏。 - 符合DI原则:不破坏容器初始化后的不可变性,遵循开闭原则,拓展性强(比如后续可添加数据库配置统一管理)。
为什么不修改已初始化的DI容器?
DI容器初始化后禁止修改是设计上的约束,强行通过反射修改会破坏容器的稳定性和代码的可预测性,工厂模式是解决动态实例管理的标准范式,也是社区推荐的方案。
内容的提问来源于stack exchange,提问作者Dani
相关产品推荐
相关产品推荐

