将用户名注入 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 也会损害单元可测试性。

有没有一种干净的方法可以做到这一点? 我正在使用 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();
        // ...
    }
}