【问题标题】:Inject username into dbContext (Entity Framework 6) to auto-update columns ModifiedBy/CreatedBy将用户名注入 dbContext (Entity Framework 6) 以自动更新列 ModifiedBy/CreatedBy
【发布时间】:2016-02-03 16:03:13
【问题描述】:

我正在设置 MVC 5、WebApi 2、实体框架解决方案。我想在我的数据库中插入审计字段,而无需每次都编写样板代码来执行此操作。我的数据库实体在他们自己的引用 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 派生类中获取userName。我认为最好的方法是将其注入 MyDbContext 构造函数?

有一些关于使用HttpContext.Current.User 的建议,但我不想在我的数据项目中添加 Web 依赖项。此外,直接引用 HttpContext 会损害单元可测试性。

  • 我已尝试在 Autofac builder.Register&lt;IPrincipal&gt;(ip =&gt; HttpContext.Current.User); 中将 IPrincipal 注入 dbcontext,但这会引发异常,因为 HttpContext.Current.User 在创建时为空。
  • 如果必须,我更愿意使用 HttpContextBase 代替 HttpContext

有没有一种干净的方法可以做到这一点? 我正在使用 Entity Framework 6、WebAPI 2、ASP NET Identity 和 Autofac。

【问题讨论】:

    标签: asp.net-mvc entity-framework asp.net-web-api asp.net-identity autofac


    【解决方案1】:

    您可以注入接口而不是 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();
            // ...
        }
    }
    

    【讨论】:

    • 是的,我现在也在想同样的事情,虽然我希望我可以使用现有的 IPrincipal。你还知道从 HttpContextBase 获取用户名的方法吗?
    猜你喜欢
    • 1970-01-01
    • 2022-11-21
    • 2016-05-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-05-29
    • 1970-01-01
    相关资源
    最近更新 更多