asp.net-mvc – 使用城堡温莎的实体框架
我使用实体框架数据库优先方法为MVC应用程序生成DbContext / POCO模型。我想避免在控制器中依赖DbContext使我能够根据需要切换到另一个持久性提供者(例如用于单元测试)。
为此,我想使用Castle Windsor IoC容器。我计划将DbContext注册为IUnitOfWork服务,并注册通用的IRepository服务,我将使用它来实现访问和使用模型中的聚合根。 我是Windsor的新人,还没有找到很多有关使用EF的信息,我有几个问题: >如果我想从应用程序中分离EF,这是一个合理的方法吗? 解决方法
所以有一些结论。我以为我会写这个,以防其他人试图使用/单元测试EF,Windsor和MVC一起使用。
首先,由于DbContext同时实现了Repository和Work of Work模式,您需要查看这些实现是否可以提供,还是需要创建自己的。 我选择创建自己的存储库,遵循DDD模式:每个聚合根一个。原因:封装查询代码,防止漏洞进入应用层,并能够在测试应用控制器时更轻松地模拟。我创建了一个基于IRepository< TEntity>的通用存储库。那里有很多例子。我发现这是一个很好的:http://architects.dzone.com/articles/implementing-repository 另一方面,我决定删除IUnitOfWork服务,而不是选择默认实现。但是,我创建了一个IDbContext抽象(不知道为什么微软本身没有这样做),所以我可以在测试Repository服务时嘲笑DbContext。 我给IDbContext只有我想在存储库中使用的DbContext的成员。所以: public interface IDbContext: IDisposable { Database Database { get; } DbEntityEntry Entry(object entity); IDbSet<TEntity> Set<TEntity>() where TEntity : class; int SaveChanges(); } 然后,我为我的IDbContext和IRepository服务创建了一个Windsor设施和安装程序: public class EntityFrameworkFacility: AbstractFacility { protected override void Init() { Kernel.Register(Component.For<IDbContext>() .ImplementedBy<MyEntities>() .LifestylePerWebRequest(),Component.For(typeof(IRepository<>)) .ImplementedBy(typeof(Repository<>)) .LifestylePerWebRequest()); } } public class PersistenceInstaller : IWindsorInstaller { public void Install(IWindsorContainer container,IConfigurationStore store) { container.AddFacility<EntityFrameworkFacility>(); } } 最后一个部分是将Entity Framework上下文类扩展为实现IDbContext,并将Set()方法映射为返回IDbSet而不是DbSet: public partial class MyEntities : IDbContext { public new IDbSet<TEntity> Set<TEntity>() where TEntity : class { return base.Set<TEntity>(); } } 有了这一切(Windsor文档中说明的ControllerFactory注册),Windsor将IRepository对象(或IDbContext)注入到控制器构造函数中变得非常简单:根据需要: public ControllerBase(IRepository<Contact> repo) { _repo = repo; } 在Repository单元测试中,真实的存储库实例可以使用模拟IDbContext进行备份: mocks = new MockRepository(); context = mocks.StrictMock<IDbContext>(); repo = new Repository<Contact>(context); 在控制器单元测试中,可以使用模拟库: mocks = new MockRepository(); repo = mocks.StrictMock<IRepository<Contact>>(); ContactController controller = new ContactController(repo); (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
- asp.net-mvc – 如何在Kendo模板中动态设置列
- asp.net – COMException未知错误(0x80005000) – Director
- C#进阶系列——WebApi 接口参数不再困惑:传参详解
- asp.net – Linux或OS X中的Web API 2.1
- asp.net – Thread.CurrentPrincipal在使用WebGet调用的WCF
- asp.net – 在后面的代码中无法识别嵌套的Repeater
- 成员资格 – 如何在ASP.NET中将用户与其各自的文件夹连接起
- 无法在asp.net中的webmethod中获取会话
- asp.net-mvc – 如何从ASP.NET MVC应用程序返回404响应?
- 是否可以还原ASP.NET预编译?
- 使用ASP.Net MVC3中的jQuery动态填充下拉列表
- asp.net – 是否可以有条件地包含CSS?
- asp.net-mvc – MVC4 Ajax表单URL
- asp.net-mvc – MVC 4中的SQL Server Express数据
- asp.net-web-api – ASP.NET Web API自定义帮助页
- ASP.NET使用VB设置文件的路径
- asp.net-mvc-3 – ASP.NET MVC – 导航当前页面突
- asp.net-mvc – asp.net MVC 3中视图模型的范围
- asp.net-core – 如何在MVC Visual Studio 2015中
- asp.net – 干净的方式来防止输入按钮提交表单