Craig
Craig

Reputation: 18734

Entity Framework business object transformation

I am trying to create a small personal project which uses EF to handle data access. My project architecture has a UI layer, a service layer, a business layer and a data access layer. The EF is contained within the DAL. I don't think it's right to then make reference to my DAL, from my UI. So I want to create custom classes for 'business objects' which is shared between all my layers.

Example: I have a User table. EF creates a User entity. I have a method to maybe GetListOfUsers(). That, in the presentation, shouldn't reply on a List, as the UI then has a direct link to the DAL. I need to maybe have a method exposed in the DAL to maybe be something like:

List<MyUserObject> GetListOfUsers();

That would then call my internal method which would GetListOfUsers which returns a list of user entities, and then transforms them into my MyUserObejcts, which is then passed back through the layers to my UI.

Is that correct design? I don't feel the UI, or business layer for that matter, should have any knowledge of the entity framework.

What this may mean, though, is maybe I need a 'Transformation layer' between my DAL and my Business layer, which transforms my entities into my custom objects?

Edit:

Here is an example of what I am doing:

I have a data access project, which will contain the Entity Framework. In this project, I will have a method to get me a list of states.

public class DataAccessor
{
    taskerEntities te = new taskerEntities();

    public List<StateObject> GetStates()
    {
        var transformer = new Transformer();
        var items =   (from s in te.r_state select s).ToList();
        var states = new List<StateObject>();
        foreach (var rState in items)
        {
            var s = transformer.State(rState);
            states.Add(s);
        }
        return states;
    }

}

My UI/Business/Service projects mustn't know about entity framework objects. It, instead, must know about my custom built State objects. So, I have a Shared Library project, containing my custom built objects:

namespace SharedLib
{

    public class StateObject
    {
        public int stateId { get; set; }
        public string description { get; set; }
        public Boolean isDefault { get; set; }
    }


}

So, my DAL get's the items into a list of Entity objects, and then I pass them through my transformation method, to make them into custom buily objects. The tranformation takes an EF object, and outputs a custom object.

public  class Transformer
    {
        public StateObject State (r_state state)
        {
            var s = new StateObject
                        {
                            description = state.description, 
                            isDefault = state.is_default, 
                            stateId = state.state_id
                        };

            return s;
        }
    }

This seems to work. But is it a valid pattern?

Upvotes: 4

Views: 3475

Answers (2)

Konstantin Chernov
Konstantin Chernov

Reputation: 1936

First, do you really need all that layers in your 'small personal project'? Second, I think your suggested architecture is a bit unclear.

If I get you right, you want to decouple your UI from your DAL. For that purpose you can for example extract interface of MyUserObject (defined in DAL obviously) class, lets call it IMyUserObject, and instead of referencing DAL from UI, reference some abstract project, where all types are data-agnostic. Also, I suggest that you'd have some service layer which would provide your presentation layer (UI) with concrete objects. If you utilize MVC you can have a link to services from your controller class. Service layer in turn can use Repository or some other technique to deal with DAL (it depends on the complexity you choose)

Considering transformation layer, I think people deal with mapping from one type to another when they have one simple model (DTO) to communicate with DB, another one - domain model, that deals with all the subtleties of business logic, and another one - presentational model, that is suited best to let user interact with. Such layering separates concerns to good measure, making each task simpler, but making app more complicated in general. So you may end having MyUserObjectDTO, MyUserObject and MyUserObjectView and some mapping or transformation btw them.

Upvotes: 1

JasCav
JasCav

Reputation: 34652

So, at some point, your UI will have to work with the data and business objects that you have. It's a fact of life. You could try to abstract farther, but that would only succeed in the interaction being deferred elsewhere.

I agree that business processes should stand alone from the UI. I also agree that your UI should not directly act with how you access your data. What have you suggested (something along the lines of "GetListOfUsers()") is known as the Repository Pattern.

The purpose of the repository pattern is to:

separate the logic that retrieves the data and maps it to the entity model from the business logic that acts on the model. The business logic should be agnostic to the type of data that comprises the data source layer

My recommendation is to use the Repository Pattern to hide HOW you're accessing your data (and, allow a better separation of concerns) and just be concerned with the fact that you "just want a list of users" or you "just want to calculate the sum of all time sheets" or whatever it is that you want your application to actually focus on. Read the link for a more detailed description.

Upvotes: 2

Related Questions