Search code examples
entity-frameworkbreezen-tier-architecture

Entity Framework and BreezeJS in a N-Tier Structure


This is kind of a specific question but I can't figure out how to get all the parts to tie together correctly. I am trying to start a project using a SQL Server database using Entity Framework to pull in data for BreezeJS with an AngularJS front end. My question is specifically focused around the N-Tier and BreezeJS relationship and how Entities need to be setup with Entity Framework to get this to work.

My project from back-end to front-end looks like this:

DAL (Data Access Layer)

Business Rules Layer

Web API Layer

AngularJS Front End

Each of these layers are in different projects and I would like to keep them separate especially the Web API and Front End so that in the future the API could be distributed without exposing the business logic.

IDEALLY the DAL layer would be more or less an Entity version of my database E.X.

Data Access Layer

public class BUILDING
{
    public BUILDING()
    {   // A List of building visitors
        this.VISITORS = new HashSet<VISITOR>();
    }

    [key]
    public int ID { get; set; }
}

public class VISITOR
{
    public VISITOR() { }

    [key]
    public int ID { get; set; }

    // The building the visitor visited
    public virtual BUILDING BUILDING { get; set; }
}

The layer above the DAL is the Business Rules which I would like the handle all the logic and data checking and really anything else that is needed. Here is where I start to have an issue. If I wanted to have a Business Rule object called ATTRACTION that encompassed the DAL objects BUILDING and VISITOR how would I go about it?

Business Rule Layer

public class ATTRACTION // This is the object I want Breeze to track
{
    private BUILDING _building;
    private List<VISITOR> _visitor;

    public int Id
    {
        get { return _building.ID }
        set { _building.ID = value; }
    }

    public void AddVisitor(int id)
    {
        // Functionality
    }
}

The Web API layer should really just mask the Business Rule layer and have little functionality and the AngularJS Front end is done.

What I'm really having trouble with is getting BreezeJS to use the object from the BR layer instead of from the DAL layer. Do I have my data set up in a way that this would be doable? I know ( or at least believe ) that BreezeJS needs DbContext items but I can't find a way to wrap the BR layer object with it. At the end of the day I want to really only use BreezeJS for its change tracking capabilities. Any help would be most appreciated and I can provide more code examples if they are needed I just wanted to keep the post at a manageable length.


Solution

  • Take a step back and ask yourself "how do the client and server communicate?"

    If the client sends lots of commands to the server ... "AddVisitor", "UpdateVisitorAddress", "GiveVisitorGoldStar" ... then you've got a messaging paradigm. Messaging paradigms are just fine. I'm not being critical of it at all. But Breeze doesn't support that paradigm particularly well.

    If the client performs mostly CRUD operations - Create, Read (query), Update and Delete ... on entity types, then you've got what I cal an "entity paradigm". Breeze has very good support for that.

    My sense is that if you're using the Web API backed by EF in front of SQL Server ... you've invested in the entity paradigm. Those technologies support the entity paradigm very well, the messaging paradigm less well.

    This question is quite apart from having an n-tier backend with business rules in their own layer.

    The DocCode example demonstrates a similar kind of separation. The Web API is in the "DocCode" project. The model layer is in the "DocCode.Models" project. And the data access layer is in the "DocCode.DataAccess.EF" layer.

    We could have put (maybe should have put) the validation logic example code in the models project. It happens to be in the the Data Access project in a class called NorthwindEntitySaveGuard. In the "real world", that class would be a dispatcher to business logic in the model classes themselves. There is some of that too ... but not much.

    DocCode also has some examples of "Dtos" which are handy in a few places.

    So ... having demonstrated that you can have such architectural separation on the server ... my question to you is ... how much of it do you really need? There is a lot of architectural flim-flam out there tempting us to over-design things.

    I DO separate my Web API controllers from my data access and model definitions. But I don't see much point in the DTO dance and the layers over layers. It certainly can be done. I rather doubt it pays off; it's more likely to make a mess in my experience. YMMV.