使用实体框架与温莎城堡(Using Entity Framework with Castle Win

2019-07-28 03:24发布

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

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

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

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

Answer 1:

因此,一些结论。 我以为我会写这件事的情况下,它是利用别人试图使用/单元测试EF,温莎和MVC一起。

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

我选择创建自己的资源库,在DDD模式如下:每个聚合根之一。 理由:封装查询代码,以防止它泄漏到应用层,和测试应用程序的控制器时,能够更容易地嘲笑。 我创建了基于通用库IRepository<TEntity> 有很多的例子在那里。 我发现这是一个很好的一个: http://architects.dzone.com/articles/implementing-repository

在另一方面,我决定放弃IUnitOfWork服务,选择了默认的实现来代替。 不过,我创建了一个抽象IDbContext(不知道为什么微软没有这样做本身),从而使测试存储库服务时,我可以嘲笑的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服务设施温莎和安装程序:

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:

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

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

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

在库单元测试,真正的存储库实例可以使用模拟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);


文章来源: Using Entity Framework with Castle Windsor