Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 5 years ago.
Improve this question
I am the lone developer on a new ASP.NET MVC project, so my ability to discuss design with peers is limited. I'd like to ensure that any change to my app in the future is confined to the layer being changed, so that the whole app doesn't have to change at once.
I'm planning to have 3 layers, each in it's own project, consisting of data layer, service/business layer, and presentation layer.
My data layer will use Entity Framework with a generic repository. This layer will return Entity types from the repo methods.
My service/business layer will be thin, but I wanted a nice separate place for business logic down the road. In the beginning, it will be nothing more than service classes for each of the major areas of my app. ie EmployeeService provides CRUD methods related to Employees that call upon the data layer. At some point, I may replace it with a Web API service layer and serve many clients.
My presentation layer will be ASP.NET MVC, with ViewModels and strongly typed views. Down the road, there may be additional clients.
I'm most interested in the communication between layers and project structure. My initial thoughts were to map data layer Entities to service layer Business Objs/Domain Objs or DTOs using AutoMapper, then mapping again to ViewModels in presentation. The mappings in the beginning would be mostly 1:1 though, so it feels redundant.
Is it a violation of DRY to have a DTO that is the same as the Entity class? That's the only way I know how to decouple from my database structure. Ideally, if I make a database change, I want to only have to change the Entities and the mappings. ie, I totally rearrange how I'm storing something and I have all new entity classes/relationships... I'd like to map the new data implementation back to the same DTO and higher layers never know.
The same repetition feeling comes up when mapping from service layer to presentation layer. My DTOs will get mapped to ViewModels. It's mostly the same stuff, but my thinking was that ViewModels also contain UI implementation details like sort fields and UI specific types like SelectListItem.
So is this actually repetition or does it just feel repetitive? Is there another way to accomplish my aim of isolating changes in layers? I'd like to be able to change or replace presentation, service or data layer with relative ease.
I recommend finding a solid (and SOLID) open source MVC project and follow that pattern. No need to re-invent the wheel -- .NET MVC is robust and there are plenty of projects that follow SOLID principles.
Take a look at NopCommerce, you can get the source code and you will see a well-architected app that answers many of your questions
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 8 years ago.
Improve this question
I need some help in making a design choice for my application. It’s a fairly straightforward web application, definitely not enterprise class or enterprise-anything.
The architecture is standard MVC 5 / EF 6 / C# ASP.NET, and the pages talk to a back-end database that’s in SQL server, and all the tables have corresponding entity objects generated from VS 2013 using the EF designer and I don’t see that changing anytime in the near future. Therefore creating super abstract “what if my database changes” etc. separations is possibly pointless. I am a one-man operation so we're not talking huge teams etc.
What I want is a clean way to do CRUD and query operations on my database, using DbContext and LINQ operations – but I’m not good with database related code design. Here are my approaches
1. Static class with methods - Should I create a static class (my DAL) that holds my datacontext and then provide functions that controllers can call directly
e.g. MyStaticDBLib.GetCustomerById(id)
but this poses problems when we try to update records from disconnected instances (i.e. I create an object that from a JSON response and need to ‘update’ my table). The good thing is I can centralize my operations in a Lib or DAL file. This is also quickly getting complicated and messy, because I can’t create methods for every scenario so I end up with bits of LINQ code in my controllers, and bits handled by these LIB methods
2. Class with context, held in a singleton, and called from controller
MyContext _cx = MyStaticDBLib.GetMyContext(“sessionKey”);
var xx = cx.MyTable.Find(id) ; //and other LINQ operations
This feels a bit messy as my data query code is in my controllers now but at least I have clean context for each session. The other thinking here is LINQ-to-SQL already abstracts the data layer to some extent as long as the entities remain the same (the actual store can change), so why not just do this?
3. Use a generic repository and unitofwork pattern – now we’re getting fancy. I’ve read a bit about this pattern, and there’s so many different advises, including some strongly suggesting that EF6 already builds the repository into its context therefore this is overkill etc. It does feel overkill but need someone here to tell me that given my context
4. Something else? Some other clean way of handling basic database/CRUD
Right now I have the library type approach (1. above) and it's getting increasingly messy. I've read many articles and I'm struggling as there's so many different approaches, but I hope the context I've given can elicit a few responses as to what approach may suit me. I need to keep it simple, and I'm a one-man-operation for the near future.
Absolutely not #1. The context is not thread safe and you certainly wouldn't want it as a static var in a static class. You're just asking for your application to explode.
Option 2 is workable as long as you ensure that your singleton is thread-safe. In other words, it'd be a singleton per-thread, not for the entire application. Otherwise, the same problems with #1 apply.
Option 3 is typical but short-sighted. The repository/unit of work patterns are pretty much replaced by having an ORM. Wrapping Entity Framework in another layer like this only removes many of the benefits of working with Entity Framework while simultaneously increasing the friction involved in developing your application. In other words, it's a lose-lose and completely unnecessary.
So, I'll go with #4. If the app is simple enough, just use your context directly. Employ a DI container to inject your context into the controller and make it request-scoped (new context per request). If the application gets more complicated or you just really, really don't care for having a dependency on Entity Framework, then apply a service pattern, where you expose endpoints for specific datasets your application needs. Inject your context into the service class(es) and then inject your service(s) into your controllers. Hint: your service endpoints should return fully-formed data that has been completely queried from the database (i.e. return lists and similar enumerables, not queryables).
While Chris's answer is a valid approach, another option is to use a very simple concrete repository/service façade. This is where you put all your data access code behind an interface layer, like IUserRepository.GetUsers(), and then in this code you have all your Entity Framework code.
The value here is separation of concerns, added testability (although EF6+ now allows mocking directly, so that's less of an issue) and more importantly, should you decide someday to change your database code, it's all in one place... Without a huge amount of overhead.
It's also a breeze to inject via dependency injection.
I found it difficult to argue with anything in this critique of ASP.net MVC's framework for page composition.
http://www.matlus.com/problems-with-asp-net-mvc-framework-design/
Particularly these points:
No access to view or partial view instances
ViewData is your loosely typed information carrier
Controller is not really in control
Child Actions have no sense of the Request Context
Views are coupled to controllers
For small applications, I don't think that a lot of these prove to be much of a problem, but in large applications where you want to reuse a lot of shared components, or even if you just have a large application that depends on multiple backend sources of information to obtain all of the information necessary to render a view, it starts to break down.
Various half-solutions to these problems have been proposed but they do not appear to scale well or have undesirable design constraints.
Here is an example application scenario:
50% of page content is common across all pages within an application (header, footer, menus, etc.)
Your application may actually be comprised of multiple areas, each with their own controllers, etc. for independent development.
A number of the page elements (menus, page header information, footers, disclosures) that are in the common page content require one or more service calls to fill out the data for rendering.
Okay, so in asp.net mvc3, let's say that you decide that you want to share a common Razor layout that contains the 50% common UI markup. This assists with Separation of Concerns in that application developers don't need to be concerned about common ui and can focus on the logic and views specific to their domain of expertise.
However, this completely breaks down in the case that this shared layout needs data (some semblance of one or more model types) to render itself completely. You may have independent elements on the page that each need a particular data model, such as:
* primary menu model
* secondary menu model
* footer links model
* authorization model
* footer disclaimers model
And each of these models may have separate sources. So although you can share the template, there is not an easy way to share the logic to build each of these models -- and there is definitely not one that is generic, extensible, and performant that I have seen.
Some approaches to this problem that I have seen are:
Strongly type the common layout, which requires all view models to subclass a common base model class. (but there is no general solution to populating such a meta-model, and this is limiting in design and makes models huge and harder to test) Additionally, model population still falls to every controller, violating the Separation of Concerns and Single Responsibility Principle and complicating unit testing controllers by piling on lots of extra logic to populate the meta-model in addition to the view-specific model information.
Leave the common layout untyped, so you don't have to inherit from a common base model, but this requires you to use ViewData or ViewBag to communicate all of the disparate models that the template needs so you lose strong typing benefits and end up with a loose data contract. You still have the problem of a lack of a general solution to populating the meta-model and all that goes along with that.
Every controller has to subclass a common base controller class to support a common layout and model. Logic for building the common aspects of the meta-model goes here. But this is not always a desirable architecture or design constraint. This does at least resolve the Separation of Concerns issues.
Instead of a meta-model, use child actions via RenderAction() in your common layout to make reusable "portlet" style widgets that each know independently how to build their data model and provide it to their view. This is really good for Separation of Concerns, but has its own litany of downsides: views effectively making service calls during rendering via the child actions, child actions are completely unaware of the original request context, violates DRY principle as each child action is unaware of what has gone before it so each could make the same service calls over and over again in the same http request, and others. Imagine 20-30 elements of a page that all needed to invoke RenderAction() independently...
There are additional cases (some seen on stackoverflow as well) where there are other problems with RenderAction() as a solution. e.g. the fact that issuing multiple RenderAction() calls in a loop results in serial execution of all of those controller methods. There is no opportunity for parallelism with RenderAction(). I/O bound service calls in each child controller action cause the whole rendering process to wait on I/O. A controller only has knowledge of its immediate view and model and nothing has a complete picture of what is going to be inside the view in order to parallelize some operations.
The author of the above critique developed a different UI model on top of ASP.Net mvc called Quartz that allows a God Controller to have intimate knowledge of the views and can hand each of them a view model so has the opportunity to parallelize service calls in a central place to build those view models. I don't know if this is the best design to provide hooks for overcoming the problems but looks promising.
My question is, what is the best practice for building a complex application on top of ASP.Net MVC that cleanly solves these problems? I have thought of a couple possibilities (although none may be practical within ASP.Net MVC--that is TBD) but someone else must have ran into this already. What are the design patterns within ASP.Net MVC or what is coming down the pike that could make this a tractable problem?
Personally, I think that the advantages of using Child Actions via RenderAction outweigh the disadvantages.
You can create 'widget' sort of elements, and wrap up their logic in a controller action - this way the view calling the widget can remain quite ignorant of what the Child Action is doing and how it is doing it - leading to a nice separation of concerns.
You have detailed the disadvantages of this approach, however I think that the negative impact can be minimised with a reasonable caching strategy.
I'm not sure there's really much more I can contribute to this "question". I think you have a good understanding of the problems and solutions, advantages and disadvantages.
In the app I'm currently working on, we utilize a couple of these approaches by having both a base model object as well as a base controller. In order to minimize roundtrips, we store some data in session and re-populate in the model by overriding the OnActionExecuted in the base controller and grab the model out of the context and set properties out of session.
I'd certainly like to hear any wonderful solutions as well, but I think these are just the tradeoffs to deal with.
I like to strive for DRY, and obviously it's not always possible. However, I have to scratch my head over a concept that seems pretty common in MVC, that of the "View Model".
The View Model is designed to only pass the minimum amount of information to the view, for both security, maintainability, and testing concerns. I get that. It makes sense.
However, from a DRY perspective, a View Model is simply duplicating data you already have. The View Model may be temporary, and used only as a DTO, but you're basically maintaing two different versions of the same model which seems to violate the DRY principal.
Do View Models violate DRY? Are they a necessary evil? Do they do more good than bad?
This has been brought up time and time again. Not only is it a pretty substantial dupe but the answer is subjective and argumentative. ViewModels are a response to DDD and the concept of persistence ignorance.
To say not using ViewModels is bad means ignoring that Django and Rails and most PHP ORM/MVC frameworks don't care at all about those concepts. Do you want somebody to tell you all those other languages and frameworks are "doing it wrong?".
Whether or not you want to use ViewModels is 100% dependent on what architecture styles you are going for and what the goals of the application are.
This is like asking is dragging and dropping GridViews in a WebForm app appropriate? Depends on a lot of things.
There is also a misconception about DRY that you have here. Do Proxy classes from a WCF service violate DRY? Does the ViewModel contain logic? The primary goal of DRY is to not have duplicated logic with a meaningful purpose. Do a couple of DTOs that share object shapres violate that?
The DDD principal of bounded contexts would make for a good read too. If a ShoppingCart object needs to function differently in a warehouse vs ecommerce website setting does that mean you to share the types? What happens when the only shared functionality is totaling a price ( price + tax + shipping )? Do you create a base class just for that therefore increasing coupling? What are the tradeoffs in time/cost/maintenance for being 100% DRY for a simple method like GetTotal(). Does violating DRY when it makes sense actually decreasing the complexity and overall cost of maintaining your codebase?
I'm sorry for answering with so many questions but hopefully now you can see the nuances and intricacies of the question you asked. ;)
One could also note that not using view models would be a violation of the single responsibility principle -- your entity should not be polluted with UI concerns.
I also think the real value of view models doesn't necessarily become apparent in version 1.0 of your application. You will thank yourself when working on version 2.0 when you completely re-think how your back-end works but you don't have to carry those changes out to the view layer.
At my company we're about to build a new site using ASP.NET MVC. My boss (marketing guy) would like to know some more about the technology so I've tried to find a really good, simple and pedagogical presentation of the MVC concept without any luck. Most of them require quite a lot of basic knowledge in programming.
Any suggestions for a good video, slides or other?
Craig Strong has a pretty nice article about MVC in general and how to explain its benefits to business. Check it out here: Updated link.
Define MVC in layman’s terms
Remember you’re technically minded and close to the code. MVC to you
is as clear as day, but saying to the business ‘Model, View,
Contoller’ could give them the impression that you are suffering from
some form tourette syndrome. MVC won’t mean much to the business even
after you define them in relation to the code. To get the business to
understand why this is the answer and least of all what it is, can be
more of a task than expected in my experience. Even some fellow
developers have difficulty understanding this on occasion.
To get the listener to understand what MVC is and why it works what I
have tried in the pass is to apply MVC to a different industries where
the listeners have had more involvement. An example that has worked
for me in the past in a comparison to the property or even the
vehicles. Most people have had dealing’s with builders, carpenters,
plumbers, electricians or have watched the flood of property shows on
the TV. This experience is a good platform to use and to explain why
separation such as MVC works. I know you’re probably thinking that
won’t work as it’s not the same as in software, but remember you’re
not trying to train the business to become developers or have an in
depth understanding of MVC, simply explaining to them that separation
in production is required and that’s what an MVC structure offers.
To give an example of how you could describe this I have very briefly
explained how separation works in property. Keep in mind this is
focused on using the system not developing which could be a completely
different angle of explanation.
View
The view in MVC is the presentation layer. This is what the end user
of a product will see and interact with. A system can have multiple
views of all different types ranging from command line output to
rendered HTML. The view doesn’t consist of business logic in most
clear designs. The interface is fit for purpose and is the area of
interaction. Therefore you could simply output HTML for consumers to
interact with or output SOAP/XML for businesses to interact with. Both
use the same business logic behind the system otherwise known as the
models and controllers.
In the world of property you could think of the view as the interior
of a property or the outer layer of a property that the inhabitants
interact with. The interior can be customised for purpose and the same
property can have many different types of tenants. For example a
property of a particular design could contain residential dwellings.
The same internal space could easily be used as office space, where
although in the same property has a different purpose. However the
property structure is the same. Therefore the environment in which the
users interact does not interfere with the structure of the building.
Controllers
The controller is where the magic happens and defines the business
application logic. This could be where the user has sent a response
from the view, then this response is used to process the internal
workings of the request and processes the response back to the user.
Taking a typical response where a user has requested to buy a book.
The controller has the user id, payment details, shipping address and
item choice. These elements are then processed through the business
logic to complete a purchase. The data is passed through the system
into the model layer and eventually after the entire request satisfies
the business definitions, the order is constructed and the user
receives their item.
If we compare this to a property, we could compare the ordering of a
book online to turning on a light switch. A tenant will flick the
switch to on just like ordering a book. The switch itself is an
element in the view layer which sends the request to the controller
just like clicking a checkout button on a web site. The business logic
in this case is what the electrician installed and are embedded within
the property designs. The switch is flicked, which completes the
circuit. Electricity runs through all the wires including the fuse box
straight through to the light bulb. Just like the user receiving a
book, in this case the tenant receives light. The whole process behind
the scenes involving the electricity cabling is not visible to the the
tenant. They simply interact with the switch within the space and from
there the controller handles the request.
Models
The models in MVC are the bottom most layer and handle the core logic
of the system. In most cases this could be seen as the layer that
interacts with the data source. In systems using MVC, the controller
will pass information to the model in order to store and retrieve
data. Following on from the example above controller definition, this
is where the order details are stored. Additional data such as stock
levels, physical location of product of the book amongst many things
are all stored here. If that was the last book in stock ordered, the
next request for this item may check if it’s available and disallow
the order as the item is no longer available.
Sticking with our example of turning on a light switch, this level in
our structure could be the electricity supply. When the tenant flicks
the switch, the internal circuit must request electricity to power the
request which is similar when the user requested data from the
database, as in data is needed to process a request. If the dwelling
isn’t connected to an electric supply, it cannot complete the process.
Business benefits from using MVC
After you get the message across explaining what MVC is, you will then
have to see what benefits can be obtained from it. I’m not going to go
into a huge amount of detail here are I’m sure you can apply benefits
more accurately which are directly related to you actual situation. To
list just some of the common benefits of an MVC based system here are
a few examples:
Different skill levels can work on different system levels. For example designers can work on the interface (View) with very little
development knowledge and developers can work on the business logic
(Controller) with very little concern for the design level. Then they
simply integrate together on completion.
As a result of the above separation projects can be managed easier and quicker. The designer can start the interfaces before the
developer and vice versa. This development process can be parallel as
opposed to being sequential therefore reducing development time.
Easy to have multiple view types using the same business logic.
Clear route through the system. You clearly know where there different levels of the system are. With a clear route of the system,
logic can be shared and improved. This has added security benefits as
you clearly know the permitted route from the data to the user and can
have clear security checks along the route.
Each layer is responsible for itself. (Relates to point 1) This means that you can have clean file structure which can be maintained
and managed much easier and quicker than a tightly couple system where
you may have lots of duplicate logic.
Having a clear structure means development will be more transparent which should result in reduced development time,
maintenance problems and release cycles if applied properly.
M-V-C Think of it as:
"Order Details (including Customer & Employee info)", "HTML/ASP Form (to display the OrderDetails)" and "Order details service class (having methods to SaveOrderDetails, GetOrderDetails etc.).
The Model (Data Class e.g. OrderDetails)
The data you want to Display
The Controller (Service class)
Knows about the Model (Order Details)
Has methods to manage the Model
And as such can be unit tested Its Single Responsibility is to manage the OrderDetails CRUD operations.
It knows NOTHING about the View
The View (ASP Page)
Displays the Model (OrderDetail's ViewData).
It has to know about the Model's structure so it can correctly display the data to the users on screen.
The View's structure (style, layout, HTML etc., locale) can be changed at anytime without it changing anything in the application's functionality.
And as such, many Views can display the same Model in many different ways.
In multi-tenant web applications, Customer specific Views can be stored in a database table and displayed based on Customer information
You have to explain the benefits of ASP.NET MVC, not the features
You have control over your URLs -- that means SEO for the site will be better -- that means your site will be higher in google
The code is cleaner, which means that it's easier to change, which means that you can add features faster
etc.
How do you save money, make money, reduce risk? That's what your boss wants to know.
Imagine a control room in a factory, the model is the machine itself, the monitoring equipment is the view and the instrument panel is the controller. You could have several different control rooms for the same machine and changes in the controls in one control room would reflect on the monitors in all control rooms.
The point is that you should only model once and then view or control however is most convenient.
The model is the data access layer, which can just be a wrapper for a few simple queries to an ORM that manages the data entity relationships itself. It handles communication to the data source, retrieves data and usually organizes it into objects defined in your application.
The views are just html files with bits of html and css with some templating engine (smarty, mako, etc) code to display the data passed to it the way you want.
The controller puts it all together. Requests made to your page will be routed to a controller (class) and an action (method) within the controller. Just like any other application, the action will do what's requested of it, but it's still part of the controller.
So, the controller uses the model to query data (users, content, etc), then passes the data to a view to be rendered and displayed the way you want.
I wouldn't try to explain the technology to him, I'd try to explain what the MVC architectural principle is all about.
MVC was designed to separate concerns. Plain and simple. Explain to him that when you build anything that what you're building can be classified in two different categories: what the business need is (the domain), and everything else.
MVC separates the Domain from the everything else by introducing layers to separate out the concerns. M is for Model, which is your domain. V is for View, which is the visible part to him, what he sees. C is for Controller, the part that controls what is going on in between the Domain and the View.
The marketing guy would just be interested in the "V" part, the View. Depending on how you design things, the View would just be basic HTML/CSS "templates" that the marketing person could modify. Technically without breaking anything.
Ideally the Model (database) and Controller (logic) shouldn't care if the View (presentation) is XML, HTML, text, etc. The marketing person shouldn't care what the Model and Controller do, except for requesting additional functionality.
Going further with the "ideal", you should technically be able to replace ASP with PHP, Java, Ruby, etc as the Controller without touching the Model or View.
You can very easily do this, that is if you understand marking speak. I dont but I imagine it would go something like this...
This should be use. MVC (if done right) will allow you to decouple the UI from the data (model) and control of the UI (controler). This will allow the UI to be more flexible which will in turn allow to better market it self faster.
To a marketing guy, perhaps the best way to explain the reason for ASP.Net MVC is the ability to broaden your product's reach.
By using MVC, the code is already separated in a fashion that will let you more easily build an interface that feels natural on a desktop, and then the different interface that caters to a general mobile device user, and a still-slightly-different interface that caters to an iPhone user, without risking the backend code getting out of sync and introducing subtle and company-harming bugs. And, if there's a smart client desktop app that could be a product... it, too, can rest on the same codebase.
The Model is "how things work inside the box". The Controller is "what you can touch on the outside of the box" and the view is "what comes out of the box"...
The most important thing for your marketing guy is money, budget, TCO ...
When you don't use MVC you usually mix design, application logic etc. alltogether.
Programmer then must know html design, programming etc... That could mean you need powerful professional to do it all.
if you use MVC, everything is divided into "separate parts". Html coder can prepare html layer, programmer only works with application logic etc...
MVC brings better granularity and everybody can focus on what he or she can do the best!
Listen, for example xhtml validity and css cleanliness is so hard that there is a lot of people who focuses only on this while lot of browsers and platforms compatibility on mind.
Usually one person is NOT the best asp.net programmer, xhtml coder in one ;-)
This is a pretty simple one
http://en.wikipedia.org/wiki/Model-view-controller#Pattern_description
The best way I can thing of is that the model is the data representation, the view is the presentation to the user and the controller is what collects user interaction that changes the model.
The important word in the title of the manager in this case is "marketing." He is a Marketing manager. The concerns one has as a marketing manager have to do with strategy and tactics. These two are not the same thing. Strategy is the big picture word that embraces among other things how a company conceptually addresses customer needs and how the company differentiates itself from its competition. Strategy is typically not what software can portray to a user. Tactics, on the other hand, are the direct methods or approaches that a company takes in winning the business of the customer. Tactics tend to change far more frequently than strategies, and it is likely that the marketing manager, when he asks what advantage MVC may give him, is really asking, "How rapidly can you change whatever it is that you create into something that conforms to new realities in the way we have to deal with customers." In other words, how quickly can you change an offer of "buy 1 and get 1 free" into "buy 2 on Friday and get 1 on the following Tuesday if it is raining in Albany."
Marketing management is about results measured in dollars and cents, not finery and nuanced explanations that are littered with conceptual words lacking any real specificity. Everything a programmer may say might make sense to himself, but a marketing manager needs to know the real likelihood of rapid response to changing customer perceptions or rapid implementation to a different approach to selling to the same customers. He needs to know if it will cost more than an existing method because if he sells $1 million more in product while spending $1.25 million in software development, he will probably lose his job.
So, in short, he is looking for flexibility and cost-effectiveness. He needs software that be adapted to changing conditions quickly, just as he changes his pitch first one way and then another to a difficult-to-persuade prospective customer, and he needs to know that he won't have to be liable for a huge price tag for that flexibility.
Frankly, I don't think that you would be able to deliver on such promises if they were made because in spite of all the advantages of MVC from a development point of view, we are still talking about software here, and as we all know, software is a rigid, demanding taskmaster that takes it own sweet time to mature to the point of trustworthiness and to be rid of its bugs. We as programmers are always in search of the holy grail of software reusability, and while we flail about trying one thing and then another (MVC, MVP, MVVM, and whatever else someone may conceive), the rest of the world is simply asking for something that works. So the best of luck to you. I hope you are able to win your case.