打造更好用的 EF 自动审计
打造更好用的 EF 自動審計
Intro
上次基于 EF Core 實現了一個自動審計的功能,詳細可以參考 EF Core 數據變更自動審計設計,雖然說多數情況下可以適用,但是因為要顯式繼承于一個 AuditDbContextBase 或 AuditDbContext,所以對代碼的侵入性比較強,對于已經無法修改的代碼或者已經繼承于某一個類了,就無法再繼承 AuditDBContext 了,就沒有辦法實現自動審計了,在 WeihanLi.EntityFramework 1.7.0 新版本里引入了 AOP 的設計,結合 AOP 來實現就簡單很多了,不再需要對原有的 DbContext 有任何修改就可以輕松實現自動審計了,下面來看如何做
實例演示
服務注冊
使用 AddProxyDbContext 代替 AddDbContext, AddProxyDbContextPool 代替 AddDbContextPool,會自動注冊代理服務,以實現 AOP 攔截
var services = new ServiceCollection(); // 使用內置的擴展注冊 DbContext 代理服務 //services.AddProxyDbContext<TestDbContext>(options => //{ // options // .UseLoggerFactory(loggerFactory) // //.EnableDetailedErrors() // //.EnableSensitiveDataLogging() // // .UseInMemoryDatabase("Tests") // .UseSqlServer(DbConnectionString) // //.AddInterceptors(new QueryWithNoLockDbCommandInterceptor()) // ; //}); // 使用內置的擴展注冊 DbContextPool 代理服務,只是為了方便使用,只會代理 DbContext services.AddProxyDbContextPool<TestDbContext>(options => {options.UseLoggerFactory(loggerFactory)//.EnableDetailedErrors()//.EnableSensitiveDataLogging()// .UseInMemoryDatabase("Tests").UseSqlServer(DbConnectionString)//.AddInterceptors(new QueryWithNoLockDbCommandInterceptor()); }); // 注冊 AOP 服務 services.AddFluentAspects(options => {// 配置使用 AuditDbContextInterceptor 攔截 DbContext 的 SaveChanges 和 SaveChangesAsync 方法options.InterceptMethod<DbContext>(m =>m.Name == nameof(DbContext.SaveChanges)|| m.Name == nameof(DbContext.SaveChangesAsync)).With<AuditDbContextInterceptor>(); }); // 注冊 serviceLocator(可選,根據自己需要 DependencyResolver.SetDependencyResolver(services);審計配置
AuditConfig.Configure(builder => {builder// 配置操作用戶獲取方式.WithUserIdProvider(EnvironmentAuditUserIdProvider.Instance.Value)//.WithUnModifiedProperty() // 保存未修改的屬性,默認只保存發生修改的屬性// 保存更多屬性.EnrichWithProperty("MachineName", Environment.MachineName).EnrichWithProperty(nameof(ApplicationHelper.ApplicationName), ApplicationHelper.ApplicationName)// 保存到自定義的存儲.WithStore<AuditFileStore>().WithStore<AuditFileStore>("logs0.log")// 忽略指定實體.IgnoreEntity<AuditRecord>()// 忽略指定實體的某個屬性.IgnoreProperty<TestEntity>(t => t.CreatedAt)// 忽略所有屬性名稱為 CreatedAt 的屬性.IgnoreProperty("CreatedAt"); });使用示例
DependencyResolver.TryInvokeService<TestDbContext>(dbContext => {dbContext.Database.EnsureDeleted();dbContext.Database.EnsureCreated();var testEntity = new TestEntity(){Extra = new { Name = "Tom" }.ToJson(),CreatedAt = DateTimeOffset.UtcNow,};dbContext.TestEntities.Add(testEntity);dbContext.SaveChanges();testEntity.CreatedAt = DateTimeOffset.Now;testEntity.Extra = new { Name = "Jerry" }.ToJson();dbContext.SaveChanges();dbContext.Remove(testEntity);dbContext.SaveChanges();var testEntity1 = new TestEntity(){Extra = new { Name = "Tom1" }.ToJson(),CreatedAt = DateTimeOffset.UtcNow,};dbContext.TestEntities.Add(testEntity1);var testEntity2 = new TestEntity(){Extra = new { Name = "Tom2" }.ToJson(),CreatedAt = DateTimeOffset.UtcNow,};dbContext.TestEntities.Add(testEntity2);dbContext.SaveChanges(); }); DependencyResolver.TryInvokeService<TestDbContext>(dbContext => {dbContext.Remove(new TestEntity(){Id = 2});dbContext.SaveChanges(); }); // disable audit AuditConfig.DisableAudit(); // enable audit // AuditConfig.EnableAudit();審計日志輸出結果
More
這樣一來就不需要修改原有代碼了~~,心情大好,哈哈~
如果應用多有多個 DbContext 有的需要審計,有的不需要審計,則可以在配置的時候指定具體的 DbContext類型如 TestDbContext,這樣就只會啟用 TestDbContext 的自動審計,別的 DbContext 比如 Test2DbContext 就不會自動審計了
Reference
https://github.com/WeihanLi/WeihanLi.EntityFramework/blob/dev/samples/WeihanLi.EntityFramework.Core3_0Sample/Program.cs
https://www.nuget.org/packages/WeihanLi.EntityFramework/
EF Core 數據變更自動審計設計
總結
以上是生活随笔為你收集整理的打造更好用的 EF 自动审计的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 面向接口编程,你考虑过性能吗?
- 下一篇: 五分钟了解dotnetcore配置框架