I will designing a couple of web applications shortly. They will probably be done in asp.net mvc.
In my existing web apps, done in delphi, the data access layer is seperated out into a completely separate application, sometimes running on a different server. This is done more for code reuse than for architectuaral reasons. This won't be a factor in the next app as it will be all new.
Is having a separate data access application overkill in a mvc app? I will already be separating out the business classes by virtue of using MVC, and I will be using an ORM to do the db persistance.
Edit: Just to clarify; I use the term tier to refer to separate physical applications, something more than just a logical separation or layer.
The term "Tier" in my experience is generally referring to physical application seperations e.g. Client Tier & Server Tier.
MVC - refers to 3 "Layers" with the concern being separation around the 3 concerns it details Model (Data), View (UI), Controller (App Logic).
Now that I have made that distinction regarding my terminology..
Is having a separate data access application overkill in a mvc app?
I would say No(again depending what you mean by application), it is not overkill, as it may in actual fact result in a more maintainable system. Your ORM will possibly allow for new data access options to be plugged in, but what if you wish to add a new ORM? Having a clearly separated Data Access Layer (DAL) will allows for much greater future flexibility in this aspect of your application.
On the other hand, depending on the scale and vision for the application creating a completely stand alone Data Access option may be overkill, but in a nutshell separation of the DAL into different assemblies is very much a recommended practice in the composition of an application implementing the MVC pattern.
Hope this helps, If you need more depth do comment.
Well I gues it depends a little on whether you're talking about tiers (pysical) or layers (logical/projects).
Regarding the layering - you could take a look at something like s#arp architecture (code.google.com/p/sharp-architecture/ ) for an example of how they do it (they have taken a pretty maximal approach to layering).
For an example of more minimalistic views here, take a look at Ayende's blog: ayende.com/Blog/
Regarding tiers - I think needlessly adding extra tiers and putting everthing over the wire will just hit your performance, unless you need to do this for capacity reasons. Get the layers right, and them seperate them into teirs as you need to adjust for capacity (should not take too much refactoring if you've seperated your concerns well).
Great comment Tobias.
I say add enough layers so that it makes sense to you and makes it easier to maintain. Also to keep a seperation of concerns.
Related
This question already has answers here:
Is the Controller in MVC considered an application service for DDD?
(4 answers)
Closed 6 years ago.
In an ASP.NET MVC world, could controllers act as the application layer, calling into my domain objects and services to get the work done (assuming the controllers just strictly calls the domain and does nothing more). In the particular case that am dealing there is very minimal application flow logic that I need to model, hence am thinking about doing away with application layer and calling the domain directly from within the controller.
Is this a fair approach?
I guess what you mean here is that your business logic is implemented using the Domain Model pattern. In such case, you application layer should be very simple, and by definition it shouldn't host any business logic. All business logic should reside in the domain layer; methods in your application layer should resemble the following steps:
Load instance of an aggregate
Execute action
Persist the updated aggregate
Return response to the user
If that's all you do in your application layer, I see no reason not to put it in the controller.
If, on the other hand, your domain model is anemic, and you do have business logic in the application layer, then I'd prefer to introduce a separate layer.
Treating your MVC controllers as your DDD application layer will present a few negative situations.
The biggest one is that your application layer (regarding DDD), is one of the key places where you model your domain/business processes. For example, you might in an application service have a method called:
PayrollService.CalculatePayslips();
This might involve, checking a domain service or external system for the current active employees, it might then need to query another domain service or external system for absences, pension deductions, etc. It will then need to call a domain service (or entity) to do the calculations.
Capturing domain/business logic like this in the MVC controllers would cause an architectural issue, should you want to trigger the task of calculating payslips from elsewhere in the system. Also if you ever wanted to expose this process as a web service, or even from another MVC controller, you would have references going across or up into your presentation layer. Solutions like these "might work", but they will contribute towards your application becoming Spaghetti Code or a Big Ball of Mud (both code smells in an architectural sense). You risk causing circular references and highly coupled code, which increases maintenance costs (both time, money, developer sanity, etc.) in the future.
At the end of the day, software development is a game of trade-offs. Architectural concerns become bigger issues, the bigger your application grows. For a lot of very small CRUD apps, architectural concerns are probably negligible. One of the key goals of DDD is to tackle complexity, so it could be argued that most DDD projects should be of sufficient complexity to be concerned about good enterprise architecture principles.
I would not do it.
The effort of creating a separate class for the application service and then invoke it from the controller is minimal. The cost is also only there when you build the application.
However, the price you have to pay once you start to maintain the application is much higher due to the high coupling between the business layer and the presentation layer.
Testing, reuse, refactoring etc is so much lower when you make sure to separate different concerns in an application.
Each Area will have its own config etc. So as the areas increases, the complexity and maintainability increases as well. Will it be good choice to modularise or partition and MVC application functionality in to Areas or continue with traditional Controller/View approach?.
Please suggest a common solution or better way to architect a large scale MVC application.
Areas shouldn't be confusing, and certainly aren't redundant. As you say, they allow you to partition your web app into smaller functional groupings. This is extremely helpful when the size of your applications grow and a single application umbrella becomes unwieldy.
As an example, I have just completed a large application that stored promotional data for various retailers across North America. The US and Canada sales teams are isolated, but are executing their tasks in nearly the same business contexts.
It made a lot of sense to partition the US and Canada parts of the web app into Areas, which organized things a lot better for us. Each area could still use the same components where they make sense (repositories, services, etc...), but the isolation Areas brought allowed us to build separate controllers and views specific to each business group, instead of trying to run a bunch of logic checks to accommodate whatever region the user was in.
Here is possible alternative to your approach from "Programming ASP.NET MVC 4" by Jess Chadwick, Todd Snyder, and Hrusikesh Panda:
There are many different approaches to take when designing an ASP.NET
MVC application. A developer can decide to keep all the application’s
components inside the website assembly, or separate components into
different assemblies. In most cases it’s a good idea to separate the
business and data access layers into different assemblies than the
website. This is typically done to better isolate the business model
from the UI and make it easier to write automated test that focuses on
the core application logic. In addition, using this approach makes it
possible to reuse the business and data access layers from other
applications (console applications, websites, web services, etc.).
A common root namespace (e.g., company.{ApplicationName}) should be
consistently used across all assemblies. Each assembly should have a
unique sub-namespace that matches the name of the assembly. Figure 5-4
shows the project structure of the Ebuy reference application. The
functionality for the application has been divided into three
projects: Ebuy.WebSite contains the view, controllers, and other
web-related files; Ebuy.Core contains the business model for the
application; and the CustomExtentions project contains the custom
extensions used by the application for model binding, routing, and
controllers. In addition, the project has two testing projects (not
shown): UnitTests and IntegrationTests.
There is no rule on whether to use Areas or not, it's basically up to solution architect to do an estimate should using areas provide benefit or not.
Our latest project that involved areas, included 3 different types of users working on the website. We used controller naming scheme where controller name matched the resource name (i.e. CategoryController).
However, certain resources could have been accessed by all 3 user groups in completely different manner: one user group could only list resource, other user group could manage them (basic crud) while the 3rd user group (admin-like) could do advanced features such as exporting, importing, etc...
By separating the functionalities in areas, we've reduced security problems by simply decorating the controller in area to request user type specific for that area, in order to avoid mixing of permissions. Doing it on the base controller for the area, made things even more centralized.
That is one reason why we would pick separation of areas.
On the other hand, we've often been in situation where we have request for a high-demanding public website and "back-office" internal configuration website. For the performance and scalability + concurrency issues, we've quite often designed public website that could be load balanced as a one project, and back-office website that would be only hosted once as a second project - instead of using areas.
Again, this is just one approach from the industry, not necessarily the optimal approach.
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.
This is a general question about design. What's the best way to communicate between your business layer and presentation layer? We currently have a object that get pass into our business layer and the services reads the info from the object and sets the result into the object. When the service are finish, we'll have a object populated with result from business layer and then the UI can display according to the result of the object.
Is this the best approach? What other approach are out there?
Domain Driven Design books (the quickly version is freely avaible here) can give you insights into this.
In a nutshell, they suggest the following approach: the model objects transverse from model tier to view tier seamlessly (this can be tricky if you are using static typed languages or different languages on clinet/server, but it is trivial on dynamic ones). Also, services should only be used to perform action that do not belong to the model objects themselves (or when you have an action that involves lots of model objects).
Also, business logic should be put into model tier (entities, services, values objects), in order to prevent the famous anemic domain model anti pattern.
This is another approach. If it suits you, it depends a lot on the team, how much was code written, how much test coverage you have, how long the project is, if your team is agile or not, and so on. Domain Driven Design quickly discusses it even further, and any decision would be far less risky if you at least skim over it first (getting the original book from Eric Evans will help if you choose to delve further).
We use a listener pattern, and have events in the business layer send information to the presentation layer.
It depends on your architecture.
Some people structure their code all in the same exe or dll and follow a standard n-tier architecture.
Others might split it out so that their services are all web services instead of just standard classes. The benefit to this is re-usable business logic installed in one place within your physical infrastructure. So single changes apply accross all applications.
Software as a service and cloud computing are becoming the platform where things are moving towards. Amazons Elastic cloud, Microsofts Azure and other cloud providers are all offering numerous services which may affect your decisions for architecture.
One I'm about to use is
Silverlight UI
WCF Services - business logic here
NHibernate data access
Sql Server Database
We're only going to allow the layers of the application to talk via interfaces so that we can progress upto Azure cloud services once it becomes more mature.
Does anyone have advice or tips on using a web service as the model in an ASP.Net MVC application? I haven't seen anyone writing about doing this. I'd like to build an MVC app, but not tie it to using a specific database, nor limit the database to the single MVC app. I feel a web service (RESTful, most likely ADO.Net Data Services) is the way to go.
How likely, or useful, is it for your MVC app to be decoupled from your database? How often have you seen, in your application lifetime, a change from SQL Server to Oracle? From the last 10 years of projects I've delivered, it's never happened.
Architectures are like onions, they have layers of abstractions above things they depend on. And if you're going to use an RDBMS for storage, that's at the core of your architecture. Abstracting yourself from the DB so you can swap it around is very much a fallacy.
Now you can decouple your database access from your domain, and the repository pattern is one of the ways to do that. Most mature solutions use an ORM these days, so you may want to have a look at NHibernate if you want a mature technology, or ActiveRecord / linq2sql for a simpler active record pattern on top of your data.
Now that you have your data strategy in place, you have a domain of some sort. When you expose data to your client, you can choose to do so through an MVC pattern, where you'll usually send DTOs generated from your domain for rendering, or you can decide to leverage an architecture style like REST to provide more loosely coupled systems, by providing links and custom representations.
You go from tight coupling to looser coupling as you go towards the external layers of your solution.
If your question however was to build an MVC app on top of a REST architecture or web services, and use that as a model... Why bother? If you're going to have a domain model, why not reuse it in your system and your services where it makes sense?
Generating a UI from an MVC app and generating documents needed for a RESTful architecture are two completely different contexts, basing one on top of each other is just going to cause much more pain than needed. And you're sacrificing performance.
Depends on your exact scenario, but remote XML-based service as the model in MVC, from experience, not a good idea, it's probably over-engineering and disregarding the need for a domain to start with.
Edit 2010-11-27; clarified my thoughts, which was really needed.
A web service exposes functionality across different types of applications, not for abstraction in one single application, most often. You are probably thinking more of a way of encapsulating commands and reads in a way that doesn't interfere with your controller/view programming.
Use a service from a service bus if you're after the decoupling and do an async pattern in your async pages. You can see Rhino.ServiceBus, nServiceBus and MassTransit for .Net native implementations and RabbitMQ for something different http://blogs.digitar.com/jjww/2009/01/rabbits-and-warrens/.
Edit: I've had some time to try rabbit out in a way that pushed messages to my service which in turn pushed updates to the book keeping app. RabbitMQ is a message broker, aka a MOM (message oriented middle-ware) and you could use it to send messages to your application server.
You can also simply provide service interfaces. Read Eric Evan's Domain Driven Design for a more detailed description.
REST-ful service interfaces deal a lot with data, and more specifically with addressable resources. It can greatly simplify your programming model and allows great control over output through the HTTP protocol. WCF's upcoming programming model uses true rest as defined in the original thesis, where each document should to some extent provide URIs for continued navigation. Have a look at this.
(In my first version of this post, I lamented REST for being 'slow', whatever that means) REST-based APIs are also pretty much what CouchDB and Riak uses.
ADO.Net is rather crap (!) [N+1 problems with lazy collection because of code-to-implementation, data-access leakage - you always need your db context where your query code is etc] in comparison to for example LightSpeed (commercial) or NHibernate. Spring.Net also allows you to wrap service interfaces in their contain with a web service facade, but (without having browsed it for a while) I think it's a bit too xmly in its configuration.
Edit 1: With ADO.Net here I mean the default "best practice" with DataSets, DataAdapter and iterating lots of rows from a DataReader; it breeds rather ugly and hard-to-debug code. The N+1 stuff, yes, that is about the entity framework.
(Edit 2: EntityFramework doesn't impress me either!)
Edit 1: Create your domain layer in a separate assembly [aka. Core] and provide all domain and application services there, then import this assembly from your specific MVC application. Wrap data access in some DAO/Repository, through an interface in your core assembly, which your Data assembly then references and implements. Wire up interface and implementation with IoC. You can even program something for dynamic service discovery with the above mentioned service buses, to solve for the interfaces. WCF uses interfaces like this and so do most of the above service busses; you can provide a subcomponentresolver in your IoC container to do this automatically.
Edit 2:
A great combo for the above would be CQRS+EventSourcing+ReactiveExtensions. Your write-model would take commands, your domain model would decide whether to accept them, it would push events to the reactive-extensions pipeline, perhaps also over RabbitMQ, which your read-model would consume.
Update 2010-01-02 (edit 1)
The jest of my idea has been codified by something called MindTouch Dream. They have made a screencast where they treat almost all parts of a web application as a (web)-service, which also is exposed with REST.
They have created a highly parallel framework using co-routines to handle this, including their own elastic thread pool.
To all the nay-sayers in this question, in ur face :p! Listen to this screen-cast, especially at 12 minutes.
The actual framework is here.
If you are into this sort of programming, have a look at how monads work and their implementations in C#. You can also read up on CoRoutines.
Happy new year!
Update 2010-11-27 (edit 2)
It turned out CoRoutines got productized with the task parallel library from Microsoft. Your Task now implement the same features, as it implements IAsyncResult. Caliburn is a cool framework that uses them.
Reactive Extensions took the monad comprehensions to the next level of asynchronocity.
The ALT.Net world seems to be moving in the direction I talked about when I wrote this answer the first time, albeit with new types of architectures I knew little of.
You should define your models in a data access agnostic way, e.g. using Repository pattern. Then you can create concrete implementations backed by specific data access technologies (Web Service, SQL, etc).
It really depends on the size of this mvc project. I would say keep the UI and Domain in same running environment if the website is going to be used by a small number of users ( < 5000).
On the other side, if you are planning on a site that is going to be accessed by millions, you have to think distributed and that means you need to build your website in a way that it can scale up/out. That means you might need to use extra servers (Web, application and database).
For this to work nicely, you need to decouple your mvc UI site from the application. The application layer would usually contain your domain model and might be exposed through WCF or a service bus. I would prefer a Service Bus because it is more reliable and might use persistent queues like msmq.
I hope this helps