繁体   English   中英

全局变量可以在dbcontext范围内使用

[英]Global variables can use in dbcontext scope

我想在我的dbcontext中访问覆盖的SaveChanges()中的某些数据,而不传递任何参数。 有什么建议么? 我正在使用MVC4和Entity Framework Database-First。

public partial class Entities : DbContext
{
    public override int SaveChanges()
    {
        // i want to get user info from MVC model but no need to pass any parameters when call SaveChanges()
        var UserInfo = userInfo;

        // Call the original SaveChanges(), which will save both the changes made and the audit records
        return base.SaveChanges();
    }
}

解决方案1:依赖注入

此解决方案可扩展性很强,但是您必须修改存储库和控制器中的代码以使用注入的依赖项,而不是使用new创建新实例。

  1. 安装Ninject。 在Visual Studio中,找到程序包管理器控制台,然后在其中运行Install-Package Ninject.MVC4 -dependencyVersion Highest

  2. 添加构造函数注入。 修改您的控制器,以使其在其构造函数中获取存储库的实例。 修改您的存储库,以使其在其构造函数中获取您的实体上下文的实例。 将依赖项缓存在私有字段中。 示例代码:

     // In your controller: public MyController(MyRepository repo) { this.repo = repo; } // In your repository: public MyRepository(Entities context) { this.context = context; } // In your entities: public Entities(UserInfo userInfo) { this.userInfo = userInfo; } 
  3. 添加一个UserInfo提供程序。 我们需要告诉Ninject从何处获取UserInfo。 我们可以在此处使用提供程序接口:

     public class UserInfoProvider : Provider<UserInfo> { protected override UserInfo CreateInstance(IContext context) { UserInfo UserInfo = new UserInfo(); // Do some complex initialization here. return userInfo; } } 
  4. 添加绑定。 我们需要告诉Ninject使用提供程序。 我们还希望将UserInfo实例和实体上下文的生存期绑定到MVC的请求周期。 更新您的App_Start \\ NinjectWebCommon.cs:

     private static void RegisterServices(IKernel kernel) { kernel.Bind<Entities>() .ToSelf() .InRequestScope(); kernel.Bind<UserInfo>() .ToProvider<UserInfoProvider>() .InRequestScope(); } 
  5. 运行您的应用。 Ninject应该使用您的构造函数并提供请求的依赖项。

有关更多信息,请访问Ninject Wiki


解决方案2:线程本地上下文

这不需要修改您的存储库,但是它使代码的可测试性较差,并且在某种程度上类似于反模式。 如果您的控制器调用多线程代码,则此方法将无效。

  1. 添加上下文类。

     public class UserInfoContext : IDisposable { private static readonly ThreadLocal<UserInfo> UserInfos = new ThreadLocal<UserInfo>(); public static UserInfo Current { get { if (UserInfos == null) { throw new InvalidOperationException("UserInfoContext has not been set."); } return UserInfos.Value; } } public static UserInfoContext Create(UserInfo userInfo) { if (userInfo == null) { throw new ArgumentNullException("userInfo"); } if (UserInfos.Value != null) { throw new InvalidOperationException("UserInfoContext should not be nested."); } UserInfos.Value = userInfo; return new UserInfoContext(); } private UserInfoContext() { } public void Dispose() { UserInfos.Value = null; } } 
  2. 包装您的控制器代码。 例:

     public ActionResult Index() { using (UserInfoContext.Create(myUserInfo)) { // do stuff that calls your repositories return View(); } } 
  3. 更新您的Entities类。

     public partial class Entities : DbContext { public override int SaveChanges() { var UserInfo = UserInfoContext.Current; // Call the original SaveChanges(), which will save both the changes made and the audit records return base.SaveChanges(); } } 

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM