使用实体框架与温莎城堡 [英] Using Entity Framework with Castle Windsor

查看:95
本文介绍了使用实体框架与温莎城堡的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用实体框架数据库第一的方针,以产生一个MVC应用程序的DbContext / POCO模式。我想避免的DbContext有依赖于我的控制器,使我能够切换到另一种持久性提供,因为我需要(例如,用于单元测试目的)。

I use the Entity Framework database-first approach to generate a DbContext / POCO model for an MVC application. I want to avoid having dependencies on DbContext in my controllers to enable me to switch to another persistence provider as I need to (for example for unit testing purposes).

要做到这一点我想使用的温莎城堡IoC容器。我打算注册的DbContext作为IUnitOfWork服务,并注册一个通用IRepository服务,实现其中我会用模型来访问,并与工作总根源。

To do this I want to use the Castle Windsor IoC container. I plan to register DbContext as an IUnitOfWork service and to register a generic IRepository service, implementations of which I will use to access and work with aggregate roots in the model.

我是新来温莎一直没能找到有关使用它与EF很多信息,我有几个问题:

I'm new to Windsor and haven't been able to find much info about using it with EF, and I have a couple of questions:


  • 这是一个合理的办法,如果我想从应用程序?
  • EF脱钩
  • 如何安装/注册IUnitOfWork和通用IRepository服务?

推荐答案

所以,一些结论。我想我会的情况下,写这篇文章了它是利用别人试图使用/单元测试EF,温莎和MVC在一起。

So, some conclusions. I thought I'd write this up in case it is of use to someone else trying to use / unit test EF, Windsor and MVC together.

首先,如实现的DbContext工作模式既库和单位,你需要查看这些实现是否会成为,或者是否需要创建自己的。

First of all, as DbContext implements both the Repository and Unit of Work patterns, you need to take view on whether these implementations will serve or whether you need to create your own.

我选择创建自己的资源库中,DDD模式如下:每个聚合根之一。原因:从泄漏到应用层封装了查询code,以prevent它,和测试应用程序控制器时,能够更轻松地嘲笑。我创建了一个基于 IRepository℃的通用信息库; TEntity&GT; 。有很多的例子在那里。我发现这是一个很好的一个:<一href=\"http://architects.dzone.com/articles/implementing-repository\">http://architects.dzone.com/articles/implementing-repository

I chose to create my own Repository, following the DDD pattern: one per aggregate root. The reasons: to encapsulate query code, to prevent it from leaking into the application layer, and to be able to mock more easily when testing the application controllers. I created a generic repository based on IRepository<TEntity>. There are plenty of examples out there. I found this a good one: http://architects.dzone.com/articles/implementing-repository

在另一方面,我决定放弃IUnitOfWork服务,选择了默认的实现来代替。不过,我创建了一个抽象IDbContext(不知道为什么微软没有这样做本身),从而使测试库服务时,我可以嘲笑的DbContext。

On the other hand I decided to drop the IUnitOfWork service, opting for the default implementation instead. However, I created an IDbContext abstraction (don't know why Microsoft didn't do this themselves), so that I could mock the DbContext when testing the Repository services.

我给IDbContext只,我想在资源库中​​使用的DbContext的成员。所以:

I gave IDbContext only the members of DbContext that I wanted to use in the repository. So:

public interface IDbContext: IDisposable
{
    Database Database { get; }
    DbEntityEntry Entry(object entity);
    IDbSet<TEntity> Set<TEntity>() where TEntity : class;
    int SaveChanges();
}

然后我创造了我的IDbContext和IRepository服务设施温莎和安装程序:

I then created a Windsor facility and installer for my IDbContext and IRepository services:

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>();
    }
}

最后一块是扩展实体框架上下文类实现IDbContext,和阴影设置()方法返回IDbSet而不是DbSet:

The final piece was to extend the Entity Framework context class to implement IDbContext, and to shadow the Set() method to return IDbSet rather than DbSet:

public partial class MyEntities : IDbContext
{
    public new IDbSet<TEntity> Set<TEntity>() where TEntity : class
    {
        return base.Set<TEntity>();
    }
}

使用此全部到位(和在温莎文档中示出的的ControllerFactory登记),变得微不足道得到温莎注入IRepository对象(或IDbContext)到控制器的构造,根据需要:

With all this in place (and the ControllerFactory registration illustrated in the Windsor docs), it becomes trivial to get Windsor to inject IRepository objects (or IDbContext) into controller constructors, as required:

public ControllerBase(IRepository<Contact> repo)
{
    _repo = repo;
}

在库单元测试,真正的存储库实例可以使用模拟IDbContext备份:

In the Repository unit tests, a real repository instance can be backed with a mock IDbContext:

mocks = new MockRepository();
context = mocks.StrictMock<IDbContext>();
repo = new Repository<Contact>(context);

在控制器单元测试,一个模拟库,可以用:

In Controller unit tests, a mock repository can be used:

mocks = new MockRepository();
repo = mocks.StrictMock<IRepository<Contact>>();
ContactController controller = new ContactController(repo);

这篇关于使用实体框架与温莎城堡的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆