12

I'm trying to work a bit with Entity Framework and I got a question regarding the separation of layers.

I usually use the UI -> BLL -> DAL approach and I'm wondering how to use EF here.

My DAL would usually be something like

GetPerson(id)
{
    // some sql
    return new Person(...)
}

BLL:

GetPerson(id)
{
    Return personDL.GetPerson(id)
}

UI:

Person p = personBL.GetPerson(id)

My question now is: since EF creates my model and DAL, is it a good idea to wrap EF inside my own DAL or is it just a waste of time?

If I don't need to wrap EF would I still place my Model.esmx inside its own class library or would it be fine to just place it inside my BLL and work some there?

I can't really see the reason to wrap EF inside my own DAL but I want to know what other people are doing.

So instead of having the above, I would leave out the DAL and just do:

BLL:

GetPerson(id)
{
    using (TestEntities context = new TestEntities())
    {
            var result = from p in context.Persons.Where(p => p.Id = id)            
                    select p;
    }
}

What to do?

Ixrec
  • 27,621
  • 15
  • 80
  • 87
mRf
  • 185
  • 1
  • 2
  • 8

3 Answers3

13

The example you provide is hardly layered architecture. I know it is intentionally simplified, but:

Your presentation layer is directly tied to the Person entity. This is OK only in simplest cases, and definitely not when you are trying to define your layers.

The GetPerson method is also using a rather bad practice of creating a new context for each call. You should get the context in the constructor, and it will be provided by your IOC container.

A simple, yet effective structure I have used is:

  • Project.Core - contains view models and interfaces.
  • Project.DAL - with my EDMX and generated code.
  • Project.BLL - business logic.
  • Project.Web - the web app itself.

It is important to note that:

  • Core is not dependent on any other solution.
  • DAL is not dependent on any other solution.
  • Project.Web depends on Core, but not on DAL nor BLL.
  • BLL depends on Core and DAL.
Boris Yankov
  • 3,573
  • 1
  • 23
  • 29
  • 1
    Core would appear to be a business object layer. – sq33G Dec 21 '11 at 10:42
  • This is pretty much what I use also, however, I'd add extra DLLs to cater for interface declarations. This way you only reference the interfaces (and use something like [url=http://unity.codeplex.com/]Unity[/url] for DI) and you can be sure that there's no weird dependencies you've accidentally induced. – Ed James Dec 21 '11 at 10:46
  • Normally, without EF i create my own Person class in a "Model" layer, so I have UI, BLL, DAL and Model where: UI knows BLL and Model. BLL knows DAL and Model. DLL knows Model. Do you create your own "view models" aswell and why dont you just use the ones EF generates? (i know this goes against the layered architecture, but how many times do you actually switch out the way you get data?) – mRf Dec 21 '11 at 11:10
  • @Thomas wrapping the view models in *something* abstract will make unit testing that much easier. – sq33G Dec 21 '11 at 11:17
  • 3
    model != view model – Boris Yankov Dec 21 '11 at 11:26
  • Can you please explain the difference and how unit testing becomes more easy? My guess on what a "ViewModel" is would be something like: If I have 2 object of which I want to show a subset of data, I combine these two objects into a new object which would be my viewmodel to show on the UI? – mRf Dec 21 '11 at 11:41
  • If you're trying to test your business logic without testing your entity model and database, you probably want to be using stub data objects. The frameworks that help with this process need abstract classes, from which they can build stubs/mocks for you. Otherwise you need to roll your own "fake" data objects for testing. – sq33G Dec 21 '11 at 12:01
  • Yes. What I do now is to have for example an IPersonRepository interface and then have PersonRepository and PersonTestRepository which implements the interface. The "Test" Repository then returns "dummy data" so I dont interact with the database. So here I would make my unit tests in my BLL using the view models? – mRf Dec 21 '11 at 12:23
  • But what if I dont have to combine two object but I just want to show a list of all Persons. Would I then create a "ViewModel" which (more or less, without the EF specific stuff) is exactly the same? I guess so? but wouldnt I, in time, have made all the generated objects from EF as my own view models? Sorry for all the question, im just trying to learn here :) – mRf Dec 21 '11 at 12:25
  • Yep, definitely that is what you will do. For example on the Edit User page you will want the full info of the Person, and on a List User page may be you want to have only the name of the person. These can be two different view models. – Boris Yankov Dec 21 '11 at 14:19
  • @Boris might be an obvious question but lets say you want to update a Person from the Web app. Web app would then call a method on the Core? But how do we go from the Core to BLL to DAL to persist to DB since Core is not dependant on any other solution – mRf Dec 22 '11 at 14:29
  • The core specifies only interfaces, so while you are actually calling a method of the BLL, but the Web only knows about a class that implements an interface. Take a look at Dependency Injection and IOC containers. These are very relevant. – Boris Yankov Dec 22 '11 at 22:52
  • I don't get it. if the WEB is connected only to CORE. And CORE is not connected to any project, What is the flow? – Hagai L May 23 '13 at 13:37
  • DAL relies on Core, but Core does not rely on anything. For example in Core, you can have a class 'Car' that has an Id and Name. But does not extend a Data Class or anything (it is POCO). Basically your Core project can have no reference to any other project (but other projects will have reference to it). – Boris Yankov May 23 '13 at 14:17
  • BLL should never depend on DAL! – Piotr Perak May 05 '14 at 20:15
  • @BorisYankov would there be a sample implementation around, which I could use as a reference .. – manishKungwani Sep 28 '15 at 13:18
2

You don't need to wrap your EDMX in anything.

If you can foresee a possibility of needing to change from EF to some other approach, you might want to extend your business objects (taking advantage of the partial classes) to implement interfaces defined in a separate Business Object layer.

Then from your code you will only deal with those interfaces and not with the concrete generated classes. A little glue code might be needed to hold this together; that with the EDMX can be your DAL.

sq33G
  • 280
  • 3
  • 12
  • So if im not foressing any changes from EF to another approach, my code above would be okay? I would then only have UI and BLL (where the EDMX is in the BLL)? – mRf Dec 21 '11 at 11:04
  • My pragmatic answer would be yes. With the caveat that you might actually want to put the EDMX in its own little assembly if it will be large and mostly static, so that you won't need to recompile/redistribute it as often. – sq33G Dec 21 '11 at 11:08
  • Ah, good point about the recompile/redistribute :) – mRf Dec 21 '11 at 11:33
2

There are two general approaches to layering: strict layering and relaxed layering.

A strictly layered approach constrains components in one layer to interacting only with peers and with the layer directly below.

A relaxed layered application loosens the constraints such that a component can interact with components from any lower layer.

Using relaxed layering can improve efficiency because the system does not have to forward simple calls from one layer to the next. On the other hand, using relaxed layering does not provide the same level of isolation between the layers and makes it more difficult to swap out a lower layer without affecting higher layers.

For large solutions involving many software components, it is common to have a large number of components at the same level of abstraction that are not cohesive. In this case, each layer may be further decomposed into one or more cohesive subsystems. Figure 2 illustrates a possible Unified Modeling Language (UML) notation for representing layers that are composed of multiple subsystems.

conclusion: if you don't need the middle layer lose it; not all applications require the same approach and somehow adding a layer just for layering purpose will have penalties on the complexity cost and maintenance.

Robert Harvey
  • 198,589
  • 55
  • 464
  • 673
omarqa
  • 442
  • 3
  • 7