一般来说,我们编写一个 Abp 模块肯定是需要构建一个配置类的,以便其他开发人员在使用我们的模块可以进行一些自定义配置。这里我们的 MongoDb 审计日志模块无非就是需要配置两个信息,第一个就是 MongoDb 数据库的连接字符串,第二个就是要存储的库名称。
/// <summary> /// 审计日志的 MongoDb 存储模块。 /// </summary> public interface IAuditingMongoDbConfiguration { /// <summary> /// MongoDb 连接字符串。 /// </summary> string ConnectionString { get; set; } /// <summary> /// 要连接的 MongoDb 数据库名称 /// </summary> string DataBaseName { get; set; } }同理,再编写一个实现。
public class AuditingMongoDbConfiguration : IAuditingMongoDbConfiguration { public string ConnectionString { get; set; } public string DataBaseName { get; set; } } 2.3 编写 IMongoClient 的工厂类其实你直接 new 也可以,这里编写一个工厂类是省去一些构建流程而已,首先为工厂类定义一个接口,该接口只有一个方法,就是创建 IMongoClient 的实例对象。
public interface IMongoClientFactory { IMongoClient Create(); }这个工厂的实现也很简单,只不过我们在工厂当中注入了 IAuditingMongoDbConfiguration ,方便我们创建实例。
public class MongoClientFactory : IMongoClientFactory { private readonly IAuditingMongoDbConfiguration _mongoDbConfiguration; public MongoClientFactory(IAuditingMongoDbConfiguration mongoDbConfiguration) { _mongoDbConfiguration = mongoDbConfiguration; } public IMongoClient Create() { return new MongoClient(_mongoDbConfiguration.ConnectionString); } } 2.4 审计日志的具体存储动作上面几点都是做一些准备工作,下面我们需要实现 IAuditingStore 接口,以便将我们的审计日志存储在 MongoDb 数据库当中。IAuditingStore 接口只定义了一个方法,就是 SaveAsync(AuditInfo auditInfo) 方法。该方法是在每次接口请求的时候,通过过滤器/拦截器的时候会被调用。当然整个审计日志的构成不是这么简单的,如果大家有兴趣可以查看我的另一篇博客 《[Abp 源码分析] 十五、自动审计记录》 ,在这篇博客有详细讲述审计日志的相关知识。
我们接着继续,因为 SaveAsync(AuditInfo auditInfo) 方法传入了一个 AuditInfo 对象,我们就可以基于这个对象来构造我们的数据实体。构造完成之后,将其通过 IMongoClient 对象存储到 MongoDb 数据库当中。
/// <summary> /// <see cref="IAuditingStore"/> 的特殊实现,使用的是 MongoDb 作为持久化存储。 /// </summary> public class MongoDbAuditingStore : IAuditingStore { private readonly IMongoClientFactory _clientFactory; private readonly IAuditingMongoDbConfiguration _mongoDbConfiguration; public MongoDbAuditingStore(IMongoClientFactory clientFactory, IAuditingMongoDbConfiguration mongoDbConfiguration) { _clientFactory = clientFactory; _mongoDbConfiguration = mongoDbConfiguration; } public async Task SaveAsync(AuditInfo auditInfo) { var entity = MongoDbAuditEntity.CreateFromAuditInfo(auditInfo); await _clientFactory.Create() .GetDatabase(_mongoDbConfiguration.DataBaseName) .GetCollection<MongoDbAuditEntity>(typeof(MongoDbAuditEntity).Name) .InsertOneAsync(entity); } }可以看到整体代码还是十分简单的,直接通过 auditInfo 对象构造好数据实体之后,插入到 MongoDb 数据库当中。
2.5 编写模块类