bugfixr
bugfixr

Reputation: 8077

.NET Entity framework project layout (architecture)

I'm trying to determine how best to architect a .NET Entity Framework project to achieve a nice layered approach. So far I've tried it out in a browse-based game where the players own and operate planets. Here's how I've got it:

Web Site

This contains all the front end.

C# Project - MLS.Game.Data

This contains the EDMX file with all my data mappings. Not much else here.

C# Project - MLS.Game.Business

This contains various classes that I call 'Managers' such as PlanetManager.cs. The planet manager has various static methods that are used to interact with the planet, such as getPlanet(int planetID) which would return an generated code object from MLS.Game.Data.

From the website, I'll do something like this:

var planet = PlanetManager.getPlanet(1);

It returns a Planet object from from the MLS.Game.Data (generated from the EDMX). It works, but it bothers me to a degree because it means that my front end has to reference MLS.Game.Data. I've always felt that the GUI should only need to reference the Business project though.

In addition, I've found that my Manager classes tend to get very heavy. I'll end up with dozens of static methods in them.

So... my question is - how does everyone else lay out their ASP EF projects?

EDIT

After some more though, there's additional items which bother me. For example, let's say I have my Planet object, which again is generated code from the wizard. What if a time came that my Planet needed to have a specialized property, say "Population" which is a calculation of some sort based on other properties of the Planet object. Would I want to create a new class that inherits from Planet and then return that instead? (hmm, I wonder if those classes are sealed by the EF?)

Thanks

Upvotes: 12

Views: 3923

Answers (7)

marc_s
marc_s

Reputation: 755157

As for your second question in the "EDIT" section:

If I'm not mistaken, the classes generated by EF are not sealed, and they are PARTIAL classes, so you could easily extend those without touching the generated files themselves.

The generated class will be:

public partial class Planet : global::System.Data.Objects.DataClasses.EntityObject
{
 ...
}

so you can easily create your own "PlanetAddons.cs" (or whatever you want to call it) to extend this class:

public partial class Planet 
{
 property int Population {get; set;} 
 ...
}

Pretty neat, eh? No need to derive and create artificial object hierarchies....

Marc

Upvotes: 1

Wayne Molina
Wayne Molina

Reputation: 19606

I would add DTOs to your Business layer that are "dumb object" representations (i.e. only properties) of the Entities in your data layer. Then your "Manager" classes can return them, such as:

class PlanetManager
{
    public static PlanetDTO GetPlanet(int id) { // ... }
}

and your UI can only deal with the BLL layer via POCOs; the Manager (what I would call a "Mapper" class) handles all the translating between the objects and the data layer. Also if you need to extend the class, you can have a "virtual" property on the DTO object and have the Manager translate that back to its components.

Upvotes: 0

Christopher Edwards
Christopher Edwards

Reputation: 6659

As for your second question (after the EDIT) if you need or want to add features to your EF objects you can use partial classes. Right click the EDMX file and select view code.

Or if this isn't enough for you can ditch the designer and write your own EF enabled classes.

There is a (brief) discussion of both options here - http://msdn.microsoft.com/en-us/library/bb738612.aspx

Upvotes: 2

Adam Ralph
Adam Ralph

Reputation: 29956

IMHO, your current layout is fine. It's perfectly normal for your UI to reference the 'Data' layer as you are calling it. I think that perhaps your concern is arising due to the terminology. The 'Data' you have described more often referred to as a 'business objects' (BOL) layer. A common layout would then be to have a business logic layer (BLL) which is your 'Managers' layer and a data access layer (DAL). In your scenario, LINQ to Entites (presuming you will use that) is your DAL. A normal reference pattern would then be:-

UI references BLL and BOL. BLL refences BOL and DAL (LINQ to Entites).

Have a look at this series of articles for more detail.

Upvotes: 2

flesh
flesh

Reputation: 23935

You could try the following to improve things:

  • Use EF to fetch DTOs in your Data layer, then use these DTOs to populate richer business objects in your Business layer. Your UI would only then need to reference the Business layer.
  • Once you have created the rich business objects, you can begin to internalise some of the logic from the manager classes, effectively cleaning up the business layer.

I personally prefer the richer model over the manager model because, as you say, you end up with a load of static methods, which you inevitibly end up chaining together inside other static methods. I find this both too messy and, more importantly, harder to understand and guarantee the consistency of your objects at any given point in time.

If you encapsulate the logic within the class itself you can be more certain of the state of your object regardless of the nature of the external caller.

A good question by the way.

Upvotes: 3

Kb.
Kb.

Reputation: 7400

Your layout looks ok. I would have added a Utility/Common layer

Web UI
Business Layer
Dataobjects
Utilities layer

Upvotes: 0

John B
John B

Reputation: 20390

I'm no expert, but that sounds pretty good to me. That similar to what I have in my solutions, except I just merge the EF project with the business project. My solutions aren't that big, and my objects don't require a lot of intelligence, so its fine for me. I too have a ton of different methods for each of my static helper classes.

If you don't want the presentation layer knowing about the data access layer, then you have to create some intermediary classes, which would probably be a lot of work. So whats the problem with your current setup?

Upvotes: 0

Related Questions