[英]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();
}
}
此解决方案可扩展性很强,但是您必须修改存储库和控制器中的代码以使用注入的依赖项,而不是使用new
创建新实例。
安装Ninject。 在Visual Studio中,找到程序包管理器控制台,然后在其中运行Install-Package Ninject.MVC4 -dependencyVersion Highest
。
添加构造函数注入。 修改您的控制器,以使其在其构造函数中获取存储库的实例。 修改您的存储库,以使其在其构造函数中获取您的实体上下文的实例。 将依赖项缓存在私有字段中。 示例代码:
// 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; }
添加一个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; } }
添加绑定。 我们需要告诉Ninject使用提供程序。 我们还希望将UserInfo实例和实体上下文的生存期绑定到MVC的请求周期。 更新您的App_Start \\ NinjectWebCommon.cs:
private static void RegisterServices(IKernel kernel) { kernel.Bind<Entities>() .ToSelf() .InRequestScope(); kernel.Bind<UserInfo>() .ToProvider<UserInfoProvider>() .InRequestScope(); }
运行您的应用。 Ninject应该使用您的构造函数并提供请求的依赖项。
有关更多信息,请访问Ninject Wiki 。
这不需要修改您的存储库,但是它使代码的可测试性较差,并且在某种程度上类似于反模式。 如果您的控制器调用多线程代码,则此方法将无效。
添加上下文类。
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; } }
包装您的控制器代码。 例:
public ActionResult Index() { using (UserInfoContext.Create(myUserInfo)) { // do stuff that calls your repositories return View(); } }
更新您的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.