toddmo
toddmo

Reputation: 22416

Entity Framework circular dll reference

My solution in it's current (sad) state:

My solution in it's current state

I want my business layer data-provider agnostic (isn't that a good thing?) with just an interface so I can switch out EF with NHibernate or Linq to Xml or whatever type of persistance provider me or my boss wants to use (or the new superior one that will inevitably be invented 2 seconds after this project is all done).

IPersistenceProvider is that interface, and I can just inject it with Unity (not the gaming platform, the DI container). To me, IPersistenceProvider belongs in the Data Layer and we can just keep adding folders (like EntityFramework) as new persistence paradigms are needed to be added to my resume (or the project).

Therefore, my business dll depends on my data dll. Here's some code in the business dll, depending on the data dll:

using System;
using Atlas.Data.Kernel;

namespace Atlas.Business.Kernel
{
  public abstract class BusinessObject
  {
    public BusinessObject(IPersistenceProvider p)
    {

    }


    public Guid Id;

  }
}

I also feel like my DatabaseContext belongs in the Data Layer. But EF makes you reference the concrete types for its DbSets, which means the AtlasDataKernel dll would need to depend on the AtlasBusinessKernel dll, which would make a circular dll reference. En plus (that's French for moreover), a Data Layer thingy pointing to the Business Layer concrete types smells to me. DatabaseContext wants to go live in the business dll, but that's coupling my business layer with a particular persistence strategy artifact.

How to resolve this? I can collapse it into one dll (and indeed, I did that very thing on a previous project), but that kinda sucks and I won't be able to get into the .Net Architects club. They will mock me for my "1 N too few" architecture and laugh me out of the meeting. WWDED? (What would Dino Esposito Do?)

Upvotes: 0

Views: 76

Answers (2)

Fredrik Rudberg
Fredrik Rudberg

Reputation: 158

Your project AtlasBusinessKernel shouldn't reference any resources in the AtalsDataKernal class. Any resources in the AtalsDataKernal that the AtalsBusinessKernel needs to use should be represented as an interface in the AtalasBusinessKernal project, could be an IDataConext interface or repository interfaces.

This only works if you have a third project which actually using the AtalsBusinessKernal project, perhaps a web application or a console application that represents the UI. This project would be responsible for instantiating the DatabaseContext, preferably using DI.

// In your AtlasDataKernal
public class DatabaseContext : IDataContext
{
      // implementation
}

// In your AtlasBusinessKernal
public class MyBusinessLogic
{
     private IDataContext dataContext;
     public MyBusinessLogic(IDataContext context)
     {
        this.dataContext = context;
     }
}
// In your web application or whatever project type it might be
public class MyWebApp
{
      public DoSomeThing()
      {
          IDataContext context = new DatabaseContext();
          MyBusinessLogic logic = new MyBusinessLogic(context);
      }
}

Upvotes: 1

devio
devio

Reputation: 37215

Split declaration from implementation.

The EntityFramework subdirectory should be a separate assembly (e.g. AtlasDataKernelEF) containing the EF stuff and the implementation of IPersistenceProvider, thus resolving the circular reference.

Also, if you should really get required to use a different ORM, you getyour production executables rid of all EF libraries.

You don't sketch how you instantiate EF data access, but you certainly need to wrap that in some kind of factory class.

Upvotes: 1

Related Questions