Reputation: 8077
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
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
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
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
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
Reputation: 23935
You could try the following to improve things:
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
Reputation: 7400
Your layout looks ok. I would have added a Utility/Common layer
Web UI
Business Layer
Dataobjects
Utilities layer
Upvotes: 0
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