简体   繁体   English

将EF6与自定义Api分离

[英]Decoupling EF6 from its custom Api

I would like to ask some help regarding Dependency Injection and, I think, architectural approach. 我想问一些有关依赖注入以及体系结构方法的帮助。

So, I have an ORM layer implemented by EF6 where the objects are described and Ef does what its business, etc. I created a custom library over it, called DatabaseApi and it is mentioned in the title as "Api", where I query the data and map it to datacontract objects. 因此,我有一个由EF6实现的ORM层,其中描述了对象,而Ef从事其业务等。我在其上创建了一个自定义库,称为DatabaseApi,并在标题中将其称为“ Api”,在其中查询数据并将其映射到datacontract对象。 I do it for pure testing purposes. 我这样做纯粹是出于测试目的。 I would like to have the different libraries in my application testable. 我想让我的应用程序中的其他库可测试。

I started to implement the code where I inject the DbContext but I don't know how to deal with the usings in this case. 我开始在注入DbContext的地方实现代码,但是在这种情况下我不知道如何处理。

I went through a few blogposts and articles about mocking and EF, especially this one but it is rather about testing EF itself and not about how to decouple it from other libraries. 我浏览了一些有关模拟和EF的博客文章和文章,特别是这篇文章, 但这只是测试EF本身,而不是如何将其与其他库分离。 On the other hand, I assume my search keywords were not proper. 另一方面,我认为我的搜索关键字不合适。

Do you know any good and usable tutorials and articles about how to decouple entity framework from other libraries? 您是否了解关于如何将实体框架与其他库分离的任何有用且有用的教程和文章?

Thanks in advance! 提前致谢!

Examples: 例子:

I created an empty interface in order to the DbContext can be injectable. 我创建了一个空接口,以便可以注入DbContext。 It is implemented by the databaseContext. 它由databaseContext实现。

public interface IDatabase
{
}

public class DatabaseModelContext : DbContext, IDatabase{

    public DbSet<TableOne> TableOne { get; set; } 
    public DbSet<TableTwo> TableTwo { get; set; }

}

In the custom Api library constructor I put together a code to resolve the interface by Unity. 在自定义的Api库构造函数中,我编写了代码以通过Unity解析接口。 I don't know whether it is working or not. 我不知道它是否有效。 I haven't executed yet. 我还没死

public partial class DatabaseApi : IDatabaseApi {
    private readonly IDatabase iDatabase;

    private readonly UnityContainer unityContainer;

    public DatabaseApi()
    {
        this.unityContainer = new UnityContainer();
        this.unityContainer.RegisterType<IDatabase, DatabaseModelContext>();
        this.iDiLibDatabase = this.unityContainer.Resolve<IDiLibDatabase>();
    }
}

And here is the problem. 这就是问题所在。 Due to the injection I'll have and interface but there are the usings which are important to manage the resource as far as I know. 由于注入,我将拥有和接口,但是据我所知,有一些用途对于管理资源很重要。 How to do it? 怎么做?

public partial class DatabaseApi : IDatabaseApi
    {
        public List<SomeDataContract> GetMainStructure()
        {
            var result = new List<SomeDataContract>();

            //this is the old implementation
            using (var database = new DatabaseModelContext())
            {
                //some data manipulation magic... :)
            }
            return result;
        }

If you're okay using linq to objects as a core element of your domain access layer then exposing an IQueryable for access to the entities would work... 如果可以将linq用作对象作为域访问层的核心元素,那么可以公开IQueryable来访问实体...

public interface IRepository<TEntity>
{
  IQueryable<TEntity> AllEntities { get; }
}

With that, you can do your Where, Select, etc. without hard wiring directly to EF. 这样,您就可以进行“位置”,“选择”等操作,而无需直接与EF进行硬接线。 Behind the scenes the IRepository implementations would deal with the EF portions, database connectivity, etc. There's no avoiding coupling the to EF at the data access layer. 在幕后,IRepository实现将处理EF部分,数据库连接性等。无法避免在数据访问层将其耦合到EF。 But you can keep it constrained to just that layer using something like you've started. 但是您可以使用类似开始的方法将其限制在该层。 Just make sure the database contexts used by your IRepository objects are the only objects working with EF. 只要确保IRepository对象使用的数据库上下文是唯一使用EF的对象即可。

Put another way: Don't have your IDatabase return entities. 换一种说法:没有IDatabase返回实体。 Just have it deal with the connections, and you should create another layer for domain object access which takes in an IDatabase. 只需处理连接,您就应该创建一个用于访问IDatabase的域对象访问的另一层。 In the example I gave, somehow the IRepository implementations would take in an instance of IDatabase. 在我给出的示例中,以某种方式,IRepository实现将采用IDatabase实例。

So, the solution is using Autofac DI framework. 因此,解决方案是使用Autofac DI框架。 I found interesting questions and answers and two really helpful tutorials. 我发现了有趣的问题和答案以及两个非常有用的教程。 Links below: 以下链接:

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

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