针对Stack Overflow问题如何在DB first方法中为实体设置创建日期和修改日期,该问题由用户LP13提出并由用户Ogglas回答。
我正在编写一个测试项目来学习新的开发方法,但遇到了困难。我正在尝试实现Ogglas提供的答案,但我不确定如何在AutoFac中注册“Wrapper”?
Ogglas和我的代码示例
public interface IEntity
{
DateTime CreatedDate { get; set; }
string CreatedBy { get; set; }
DateTime UpdatedDate { get; set; }
string UpdatedBy { get; set; }
}
public interface IAuditableEntity
{
DateTime CreatedDate { get; set; }
string CreatedBy { get; set; }
DateTime UpdatedDate { get; set; }
string UpdatedBy { get; set; }
}
public interface ICurrentUser
{
string GetUsername();
}
public interface ICurrentUser
{
string Name();
string GetUserId();
bool IsUserAuthenticated();
bool IsUserAdmin();
bool IsUserManager();
}
public class ApplicationDbContextUserWrapper
{
public ApplicationDbContext Context;
public ApplicationDbContextUserWrapper(ApplicationDbContext context, ICurrentUser currentUser)
{
context.CurrentUser = currentUser;
this.Context = context;
}
}
public class MyDbContextWrapper
{
public IMyDbContext Context;
public MyDbContextWrapper(IMyDbContext context, ICurrentUser currentUser)
{
context.CurrentUser = currentUser;
Context = context;
}
}
public class ApplicationDbContext : DbContext
{
public ICurrentUser CurrentUser;
public override int SaveChanges()
{
var now = DateTime.Now;
foreach (var changedEntity in ChangeTracker.Entries())
{
if (changedEntity.Entity is IEntity entity)
{
switch (changedEntity.State)
{
case EntityState.Added:
entity.CreatedDate = now;
entity.UpdatedDate = now;
entity.CreatedBy = CurrentUser.GetUsername();
entity.UpdatedBy = CurrentUser.GetUsername();
break;
case EntityState.Modified:
Entry(entity).Property(x => x.CreatedBy).IsModified = false;
Entry(entity).Property(x => x.CreatedDate).IsModified = false;
entity.UpdatedDate = now;
entity.UpdatedBy = CurrentUser.GetUsername();
break;
}
}
}
return base.SaveChanges();
}
}
public class MyDbContext : DbContext, IMyDbContext
{
public ICurrentUser CurrentUser { get; set; }
public DbSet<Staff> Staff { get; set; }
public DbSet<AddressStaff> StaffAddresses { get; set; }
public MyDbContext() : base("Name=MyWebPortalConnection")
{
Database.SetInitializer(new MigrateDatabaseToLatestVersion<MyDbContext, MyWebPortalContextMigrationConfiguration>());
}
public override int SaveChanges()
{
var modifiedEntries = ChangeTracker.Entries().Where(x => x.Entity is IAuditableEntity
&& (x.State == EntityState.Added
|| x.State == EntityState.Modified));
foreach (var entry in modifiedEntries)
{
if (entry.Entity is IAuditableEntity entity)
{
var dateTimeZone = DateTimeZoneProviders.Tzdb["Europe/London"];
var zonedClock = SystemClock.Instance.InZone(dateTimeZone);
var localDateTime = zonedClock.GetCurrentLocalDateTime();
var dateTime = new DateTime(localDateTime.Year,
localDateTime.Month,
localDateTime.Day,
localDateTime.Hour,
localDateTime.Minute,
localDateTime.Second);
if (entry.State == EntityState.Added)
{
entity.CreatedBy = CurrentUser.Name();
entity.CreatedDate = dateTime;
}
else if (entry.State == EntityState.Modified)
{
entity.UpdatedBy = CurrentUser.Name();
entity.UpdatedDate = dateTime;
}
else
{
Entry(entity).Property(x => x.CreatedBy).IsModified = false;
Entry(entity).Property(x => x.CreatedDate).IsModified = false;
}
}
}
return base.SaveChanges();
}
我的 AutoFac EF 模块已更新
public class EFModule : Module
{
protected override void Load(ContainerBuilder builder)
{
//builder.RegisterType<MyDbContextWrapper>().As<IMtDbContext>();
//builder.RegisterDecorator<MyDbContextWrapper, IMyDbContext>();
//builder.RegisterDecorator<MyDbContextWrapper, IMyDbContext>();
builder.RegisterType<MyDbContextWrapper>().AsSelf().InstancePerLifetimeScope();
builder.RegisterType(typeof(MyDbContext)).As(typeof(IMyDbContext)).As(typeof(DbContext)).InstancePerLifetimeScope();
builder.RegisterType(typeof(UnitOfWork)).As(typeof(IUnitOfWork)).InstancePerRequest();
builder.Register(_ => new HttpClient()).As<HttpClient>().InstancePerLifetimeScope();
}
}
我已经使用以下教程作为设置我的项目的指南Tutorial Guide Project。非常感谢您提供的任何帮助。谢谢。
通用存储库已更新
public abstract class GenericRepository<T> : IGenericRepository<T> where T : BaseEntity
{
protected MyDbContextWrapper DbContextWrapper;
protected DbContext GenericDbContext;
protected readonly IDbSet<T> GenericDbset;
protected GenericRepository(MyDbContextWrapper dbContextWrapper)
{
DbContextWrapper = dbContextWrapper;
GenericDbContext = (DbContext)DbContextWrapper.Context;
GenericDbset = GenericDbContext.Set<T>();
}
IMyDbContext已更新
public interface IMyDbContext
{
ICurrentUser CurrentUser { get; set; }
DbSet<Staff> Staff { get; set; }
DbSet<AddressStaff> StaffAddresses { get; set; }
int SaveChanges();
}
我的 CurrentUser AutoFac 模块
public class CurrentUserModule : Autofac.Module
{
protected override void Load(ContainerBuilder builder)
{
builder.RegisterAssemblyTypes(Assembly.Load("MyWebPortal.Model"))
.Where(t => t.Name.EndsWith("User"))
.AsImplementedInterfaces()
.InstancePerLifetimeScope();
}
}