2

I'd like to create a good app in ASP.NET MVC 5 using EF 6 Code first concept. I want it to be well-designed i.e. having generally speaking: Presentation, Logic and Data layers separated. I want it to be testable :)

Here's my idea and some issues related with creating application

Presentation layer: It's my whole MVC - view models(not models), views, controllers I believe that's validation should be done somewhere else (in my opinion - it's a part of business logic) but it's quite convenient to use attributes from the DataAnnotations namespace in ViewModelds and check validation in controller.

Logic layer: Services - classes with their interfaces to rule business logic. I put there functions like: AddNewPerson(PersonViewModel Person), SendMessageToPerson(...). They will use DB context to make their actions (there's a chance that not all of them will be relying on context). There's a direct connection between service and db - I mean the service class have reference do context. Where should I do mapping between ViewModel and Model? I've heard that service is a bad place for it - so maybe in controllers. I've heard that service should do the work related with db exclusively. Is it right? Is my picture of service layer is good?

Data layer: I've read about Repository and UoW patterns a lot. There're some articles which suggest that EF6 implements these two things. I don't want to create extra code if there's no need for such a behavior. The question is: am i right to assume that i don't need them?

Here's my flow:

View<->Controllers(using ViewModels)<->Services(using Models)<->DB.

**I'm gonna use DI in my project.

What do you think about my project structure?

WaltLift0
  • 43
  • 1
  • 5

2 Answers2

4

There is no reason to use a Unit of Work pattern with Entity Framework if you have no need to create a generic data access mechanism. You would only do this if you were:

  1. using a data access technology that did not natively support a Unit of work pattern (EF does)
  2. Wanted to be able to swap out data providers sometime in the future.. however, this is not as easy as it might seem as it's very hard NOT to introduce dependencies on specific data technologies even when using an Unit of Work (maybe even BECAUSE you are)... or
  3. You need to have a way of unifying disparate data sources into an atomic transaction.

If none of those are the case, you most likely don't need a custom Unit of Work. A Repository, on the other hand can be useful... but with EF6 many of the benefits of a Repository are also available since EF6 provides mocking interfaces for testing. Regardless, stay away from a generic repository unless it's simply an implementation detail of your concrete repositories. Exposing generic repositories to your other layers is a huge abstraction leak...

I always use a Repository/Service/Façade pattern though to create a separation between my data and business (and UI and business for that matter) layers. It provides a convenient way to mock without having to mock your data access itself and it decouples your logic from the specific that are introduced by the Linq layer used by EF (Linq is relatively generic, but there are things that are specific to EF), a façade/repository/server interface decouples that).

In general, you're on the right path... However, let me point out that using Data Attributes on your view models is a good thing. This centralizes your validation on your model, rather than making you put validation logic all over the place.

You're correct that you need validation in your business logic as well, but your mistake is the assumption that you should only have it on the business logic. You need validation at all layers of your application.. And in particular, your UI validation may have different requirements than your business logic validation.

For instance, you may implement creating a new account as a multi-step wizard in your UI, this would require different validation than your business layer because each step has only a subset of the validation of the total object. Or you might require that your mobile interface has different validation requirements from your web site (one might use a captcha, while the other might use a touch based human validation for instance).

Either way, it's important to keep in mind that validation is important both at the client, server, and various layers...

Erik Funkenbusch
  • 92,674
  • 28
  • 195
  • 291
  • Thank you Erik. I see your point. You've mentioned about validation - I see your point. What exactly are Repository and Façade in your in your project? – WaltLift0 Sep 12 '14 at 18:04
  • @WaltLift0 - Repository pattern is really just a specialized façade pattern. It's putting your real implementation behind an interface to separate it so neither side knows about the other. – Erik Funkenbusch Sep 12 '14 at 18:31
1

Ok, let’s clarify a few things...

The notion of ViewModel (or the actual wording of ViewModel) is something introduced by Microsoft Martin Fowler. In fact, a ViewModel is nothing more than a simple class.

In reality, your Views are strongly typed to classes. Period. To avoid confusion, the wording ViewModel came up to help people understand that

“this class, will be used by your View”

hence why we call them ViewModel.

In addition, although many books, articles and examples use the word ViewModel, let's not forget that it's nothing more than just a Model.

In fact, did you ever noticed why there is a Models folder inside an MVC application and not a ViewModels folder?

Also, ever noticed how at the top of a View you have @model directive and not @ viewmodel directive?

That's because everything could be a model.

By the way, for clarity, you are more than welcomed to delete (or rename) the Models folder and create a new one called ViewModels if that helps.

Regardless of what you do, you’ll ultimately call @model and not @viewmodel at the top of your pages.

Another similar example would be DTO classes. DTO classes are nothing more than regular classes but they are suffixed with DTO to help people (programmers) differentiate between all the other classes (including View Models).

In a recent project I’ve worked on, that notion wasn’t fully grasped by the team so instead of having their Views strongly typed to Models, they would have their Views strongly typed to DTO classes. In theory and in practice everything was working but they soon found out that they had properties such as IsVisible inside their DTO’s when in fact; these kind of properties should belongs to your ViewModel classes since they are used for UI logic.

So far, I haven’t answered your question but I do have a similar post regarding a quick architecture. You can read the post here

Another thing I’d like to point out is that if and only if your Service Layer plans on servicing other things such as a Winform application, Mobile web site, etc...then your Service Layer should not be receiving ViewModels.

Your Service Layer should not have the notion of what is a ViewModel. It should only accept, receive, send, etc... POCO classes.

This means that from your Controller, inside your ActionResult, once the ModelState is Valid, you need to transform your ViewModel into a POCO which in turn, will be sent to the method inside your Service Layer.

In other words, I’d use/install the Automapper nugget package and create some extension methods that would convert a ViewModel into a POCO and vice-versa (POCO into a ViewModel).

This way, your AddNewPerson() method would receive a Person object for its parameter instead of receiving a PersonViewModel parameter.

Remember, this is only valid if and only if your Service Layer plans on servicing other things...

If that's not the case, then feel free to have your Service Layer receive, send, add, etc...ViewModels instead of POCOs. This is up to you and your team.

Remember, there are many ways to skin a cat.

Hope this helps.

Community
  • 1
  • 1
Vlince
  • 5,885
  • 7
  • 45
  • 62
  • 1
    Incorrect. The notion of a ViewModel was created by Martin Fowler, although he called it a "Presentation Model", and it's defined in his Presentation Model pattern. See http://martinfowler.com/eaaDev/PresentationModel.html - By the way, it's called NuGet, not nugget. I only mention it since you seem like such a stickler for nomenclature. – Erik Funkenbusch Sep 11 '14 at 21:15
  • Correct, the French version of Word I use ignored the mistake. Thanks for the correction :-) – Vlince Sep 11 '14 at 22:07
  • Thank you Vlince. You let me understand some issues. Going back to differences between Model and ViewModel. I think that they're imitating a little bit different things: Model - business object, ViewModel - selected items from business object + some additional stuff for a end user. – WaltLift0 Sep 12 '14 at 18:24