1

Let's assume we have an ASP.NET MVC web application with following tiers:

  • Business logic
  • Entities (business domain and database POCOs)
  • Common (resources, consts)
  • Data access (database EF queries, EDMX EF models and so on)
  • Web application (MVC web application)

We're using view models approach. Currently view models are placed in Entities layer. Data access queries returns view models (due to efficiency issues, so we avoid using mapper).

Web layer references all other layers. Data access references Common and Entities layers. Business logic references Entities and Common layers, in the future also Data access layer.

There's an idea to move view models to Web layer. Why? Because they're in fact bound with a particular technology (MVC) and UI implementation. But we're facing a problem here, because in this scenario Data access layer must reference Web and Web references Data access, so we have a circular dependency issue.

Moreover we have scenario when some validation of view model requires reference to Data access layer. We're going to keep validation method inside view models. Currently we want to implement it by injecting database context class (which is in Data access layer) to view model by constructor.

Do you have any idea how can we avoid it? Is it good idea to keep view models inside our Web layer?

Arkadiusz Kałkus
  • 17,101
  • 19
  • 69
  • 108
  • How do you avoid mapping the objects even with a viewmodel? Why must the Web project reference the Data Access project? Also why must the viewmodels reference the data access project for validation? –  Apr 03 '15 at 11:44
  • @gerdi Avoiding mapping objects is achieved by returning view model. So EF query has at end "select new SomeVM { fields = sth }" line. Web references Data access because DAL exposes methods for querying DB which are used in controllers. Viewmodels must have injected reference to data access project because some validation methods must check something in the database to validate view model (and we have Validation method in view models). – Arkadiusz Kałkus Apr 03 '15 at 11:48
  • You dont state if you are using Dependency Injection , this sounds like something for an IoC container. –  Apr 03 '15 at 11:58
  • We're not using DI because some other aspects of our architecture make it too tough to implement. I said injecting, but in fact we're creating object which accesses db (let's say our unit of work object) in the base controller. Then we pass reference in view model constructor so it can use it in its validate method. Anyway - IoC is not an answer because we can't use it. – Arkadiusz Kałkus Apr 03 '15 at 12:13
  • Well that would be one way of avoiding the run around. But honestly i dont think it is too much a concern which project the viewmodels are in. In a Default asp mvc project they are in the "web" section . Because VM's are purely a new entity for the UI Layer. It might even be more in line with separation of concerns to have them in the web project. –  Apr 03 '15 at 12:28

1 Answers1

3

I'm unsure how you can use ViewModel in web apps. AFAIK it's harder than in desktop app due to it's data-binding nature.

However, your web layer referenced directly to data layer (or rather, access directly). Unless it is used to help simplify the UI and not the business process, it is breaking the purpose of N-tier aswell.

What you need to do to keep the design clean is making 2 different model. One for Entities model (Domain/data/business model) and another for view model. Your view model is placed at web layer and when received the domain model, it is being mapped to web layer. You cannot avoid mapping here.

Community
  • 1
  • 1
Fendy
  • 4,565
  • 1
  • 20
  • 25
  • AFAIK the purpose of using view model approach instead of models is to avoid usage of ViewBag and simplify the views. Using domain models not always fit the needs of views. As I wrote in another comment here, we decided to return view models instead of domain models to avoid mapping overhead. I know it's not "clean" from architecture point of view, but it was just too slow. Thank you for you answer, it ensures me that it's impossible to have view models in the web project in our approach (I thought so but my team wasn't sure). – Arkadiusz Kałkus Apr 08 '15 at 07:08
  • @Landeeyo it is, unfortunately. If you go for performance, it is harder to keep for clean architecture and vice versa. However, usually the mapping does not come as costly as you think. – Fendy Apr 08 '15 at 07:21
  • For us it took about 10 times more to do the same using AutoMapper. Though I'm not sure if we didn't make something wrong... – Arkadiusz Kałkus Apr 08 '15 at 08:22
  • Have you tried using conventional code mapping? AFAIK `AutoMapper` use reflection and is slower rather than conventional code mapping. – Fendy Apr 08 '15 at 10:06
  • Conventional code mapping of course wouldn't cause overhead, but would cost development effort on the other hand. – Arkadiusz Kałkus Apr 08 '15 at 11:39
  • 1
    @Landeeyo I agree. It is when the code generation tools come in hand – Fendy Apr 08 '15 at 14:49
  • I've never thought about it in this situation, but it's a great idea. Fast google query have not gave me obvious results in that matter. Could you recommend me any code generation tools? – Arkadiusz Kałkus Apr 08 '15 at 18:21
  • @Landeeyo I use code generation tools I've developed myself internally. I think there must be many premium code generator tools out there. In case of curiosity, I've developed one template based code generator tools, with C# class as input, roslyn and stringtemplate. It's buggy currently though, so please understand :). https://smartflow.wordpress.com/mapper-generator/ – Fendy Jul 08 '15 at 09:29