将用户名注入 dbContext (Entity Framework 6) 以自动更新列 ModifiedBy/CreatedBy
Inject username into dbContext (Entity Framework 6) to auto-update columns ModifiedBy/CreatedBy
我正在设置 MVC 5、WebApi 2、Entity Framework 解决方案。我想在我的数据库中插入审计字段,而不必每次都编写样板代码来执行此操作。我的数据库实体位于引用 EntityFramework.
的独立项目中
到目前为止我有:
public class MyDbContext : IdentityDbContext<ApplicationUser>
{
public MyDbContext(/*Autofac can inject stuff here*/)
{
}
public override int SaveChanges()
{
// Updates ModifiedBy, CreatedBy, ModifiedOn, CreatedOn fields
DbContextHelper.TrackSaveChanges(ChangeTracker, userName);
return base.SaveChanges();
}
}
TrackSaveChanges()
中的逻辑并不重要,这只是遍历所有已更改的实体并在字段上设置值。没什么太聪明的。
问题是在我的 DbContext
派生的 class 中获取 userName
。我认为最好的方法是在 MyDbContext
构造函数中注入它?
有关于使用 HttpContext.Current.User
的建议,但我不想向我的数据项目添加 Web 依赖项。直接引用 HttpContext
也会损害单元可测试性。
- 我曾尝试在 Autofac
builder.Register<IPrincipal>(ip => HttpContext.Current.User);
中将 IPrincipal
注入 dbcontext,但这会引发异常,因为 HttpContext.Current.User 在创建时为空。
- 如果必须,我更愿意使用
HttpContextBase
代替 HttpContext
。
有没有一种干净的方法可以做到这一点?
我正在使用 Entity Framework 6、WebAPI 2、ASP NET Identity 和 Autofac。
您可以注入接口而不是 string
值本身:
interface IUserNameProvider
{
string GetUserName();
}
具体实现将使用HttpContext.Current.User
,但这种方法不会损害可测试性,因为接口很容易被模拟。
interface HttpContextUserNameProvider : IUserNameProvider
{
public string GetUserName()
{
return HttpContext.Current.User;
}
}
客户端代码示例:
public class MyDbContext : IdentityDbContext<ApplicationUser>
{
internal IUserNameProvider _userNameProvider;
public MyDbContext(IUserNameProvider userNameProvider)
{
_userNameProvider = userNameProvider;
}
public override int SaveChanges()
{
string userName = _userNameProvider.GetUserName();
// ...
}
}
我正在设置 MVC 5、WebApi 2、Entity Framework 解决方案。我想在我的数据库中插入审计字段,而不必每次都编写样板代码来执行此操作。我的数据库实体位于引用 EntityFramework.
的独立项目中到目前为止我有:
public class MyDbContext : IdentityDbContext<ApplicationUser>
{
public MyDbContext(/*Autofac can inject stuff here*/)
{
}
public override int SaveChanges()
{
// Updates ModifiedBy, CreatedBy, ModifiedOn, CreatedOn fields
DbContextHelper.TrackSaveChanges(ChangeTracker, userName);
return base.SaveChanges();
}
}
TrackSaveChanges()
中的逻辑并不重要,这只是遍历所有已更改的实体并在字段上设置值。没什么太聪明的。
问题是在我的 DbContext
派生的 class 中获取 userName
。我认为最好的方法是在 MyDbContext
构造函数中注入它?
有关于使用 HttpContext.Current.User
的建议,但我不想向我的数据项目添加 Web 依赖项。直接引用 HttpContext
也会损害单元可测试性。
- 我曾尝试在 Autofac
builder.Register<IPrincipal>(ip => HttpContext.Current.User);
中将IPrincipal
注入 dbcontext,但这会引发异常,因为 HttpContext.Current.User 在创建时为空。 - 如果必须,我更愿意使用
HttpContextBase
代替HttpContext
。
有没有一种干净的方法可以做到这一点? 我正在使用 Entity Framework 6、WebAPI 2、ASP NET Identity 和 Autofac。
您可以注入接口而不是 string
值本身:
interface IUserNameProvider
{
string GetUserName();
}
具体实现将使用HttpContext.Current.User
,但这种方法不会损害可测试性,因为接口很容易被模拟。
interface HttpContextUserNameProvider : IUserNameProvider
{
public string GetUserName()
{
return HttpContext.Current.User;
}
}
客户端代码示例:
public class MyDbContext : IdentityDbContext<ApplicationUser>
{
internal IUserNameProvider _userNameProvider;
public MyDbContext(IUserNameProvider userNameProvider)
{
_userNameProvider = userNameProvider;
}
public override int SaveChanges()
{
string userName = _userNameProvider.GetUserName();
// ...
}
}