The Purpose of a Service Layer and ASP.NET MVC 2 - asp.net

In an effort to understand MVC 2 and attempt to get my company to adopt it as a viable platform for future development, I have been doing a lot of reading lately. Having worked with ASP.NET pretty exclusively for the past few years, I had some catching up to do.
Currently, I understand the repository pattern, models, controllers, data annotations, etc. But there is one thing that is keeping me from completely understanding enough to start work on a reference application.
The first is the Service Layer Pattern. I have read many blog posts and questions here on Stack Overflow, but I still don't completely understand the purpose of this pattern. I watched the entire video series at MVCCentral on the Golf Tracker Application and also looked at the demo code he posted and it looks to me like the service layer is just another wrapper around the repository pattern that doesn't perform any work at all.
I also read this post: http://www.asp.net/Learn/mvc/tutorial-38-cs.aspx and it seemed to somewhat answer my question, however, if you are using data annotations to perform your validation, this seems unnecessary.
I have looked for demonstrations, posts, etc. but I can't seem to find anything that simply explains the pattern and gives me compelling evidence to use it.
Can someone please provide me with a 2nd grade (ok, maybe 5th grade) reason to use this pattern, what I would lose if I don't, and what I gain if I do?

In a MVC pattern you have responsibilities separated between the 3 players: Model, View and Controller.
The Model is responsible for doing the business stuff, the View presents the results of the business (providing also input to the business from the user) while the Controller acts like the glue between the Model and the View, separating the inner workings of each from the other.
The Model is usually backed up by a database so you have some DAOs accessing that. Your business does some...well... business and stores or retrieves data in/from the database.
But who coordinates the DAOs? The Controller? No! The Model should.
Enter the Service layer. The Service layer will provide high service to the controller and will manage other (lower level) players (DAOs, other services etc) behind the scenes. It contains the business logic of your app.
What happens if you don't use it?
You will have to put the business logic somewhere and the victim is usually the controller.
If the controller is web centric it will have to receive its input and provide response as HTTP requests, responses. But what if I want to call my app (and get access to the business it provides) from a Windows application which communicates with RPC or some other thing? What then?
Well, you will have to rewrite the controller and make the logic client agnostic. But with the Service layer you already have that. Yyou don't need to rewrite things.
The service layer provides communication with DTOs which are not tied to a specific controller implementation. If the controller (no matter what type of controller) provides the appropriate data (no mater the source) your service layer will do its thing providing a service to the caller and hiding the caller from all responsibilities of the business logic involved.

I have to say I agree with dpb with the above, the wrapper i.e. Service Layer is reusable, mockable, I am currently in the process of including this layer inside my app... here are some of the issues/ requirements I am pondering over (very quickly :p ) that could be off help to youeself...
1. Multiple portals (e.g. Bloggers portal, client portal, internal portal) which will be needed to be accessed by many different users. They all must be separate ASP.NET MVC Applications (an important requirement)
2. Within the apps themselves some calls to the database will be similar, the methods and the way the data is handled from the Repository layer. Without doubt some controllers from each module/ portal will make exactly or an overloaded version of the same call, hence a possible need for a service layer (code to interfaces) which I will then compile in a separate class project.
3.If I create a separate class project for my service layer I may need to do the same for the Data Layer or combine it with the Service Layer and keep the model away from the Web project itself. At least this way as my project grows I can throw out the data access layer (i.e. LinqToSql -> NHibernate), or a team member can without working on any code in any other project. The downside could be they could blow everything up lol...

Related

how to wire-in domain event handlers in multi-layer applications

So my question is very much related to this one: Entity persitance inside Domain Events using a repository and Entity Framework?
EDIT: A much better discussion on the topic is also here: Where to raise persistence-dependent domain events - service, repository, or UI?
However my question is rather more simple and technical, assuming that I'm taking the right approach.
Let's suppose I have the following projects:
MyDomainLayer -> very simple classes, Persitence Ignorance, a.k.a POCOs
MyInfrastructureLayer -> includes code for repositories, Entity Framework
MyApplicationLayer -> includes ASP.Net MVC controllers
MyServicesLayer -> WCF-related code
MyWebApplication -> ASP.Net MVC (Views, Scripts, etc)
When an event is raised (for example a group membership has been granted),
then two things should be done (in two different layers):
To Persist data (insert a new group membership record in the DB)
To Create a notification for the involved users (UI related)
I'll take a simple example of the last reference I wrote in the introduction:
The domain layer has the following code:
public void ChangeStatus(OrderStatus status)
{
// change status
this.Status = status;
DomainEvent.Raise(new OrderStatusChanged { OrderId = Id, Status = status });
}
Let's assume the vent handler is in MyApplicationLayer (to be able to talk to the Services Layer).
It has the following code:
DomainEvent.Register<OrderStatusChanged>(x => orderStatusChanged = x);
How does the wire-in happen? I guess is with structuremap, but how does this wire-in code looks exactly?
First, your layering isn't exactly right. Corrections:
Application Layer - ASP.NET MVC controllers are normally thought of as forming an adapter between your application layer and HTTP/HTML. Therefore, the controllers aren't themselves part of the application layer. What belongs in application layer are application services.
MyServicesLayer - WCF-related code. WCF implemented services are adapters in the hexagonal architecture referenced by Dennis Traub.
MyWebApplication - ASP.Net MVC (Views, Scripts, etc). Again, this forms an adapter in a hexagonal architecture. MVC controllers belong here as well - effectively they are implementation detail of this adapter. This layer is very similar to service layer implemented with WCF.
Next, you describe 2 things that should happen in response to an event. Persistence is usually achieved with committing a unit of work within a a transaction, not as a handler in response to an event. Also, notifications should be made after persistence is complete, or in other words after the transaction is committed. This is best done in an eventually consistent manner that is outside of the unit of work that generated the domain event in the first place.
For specifics on how to implement a domain event pub/sub system take a look here.
My first recommendation, get rid of the notion of Layers and make yourself familiar with the concept of a Hexagonal Architecture a.k.a. Ports and Adapters.
With this approach it is much easier to understand how the domain model can stay independent of any of the surrounding concerns. Basically that is object-orientation on an architectural level. Layers are procedural.
For your specific problem, you might create a project containing the event handlers that project events into the database. These handlers can have direct access to the database or go through an ORM. You probably won't need any repositories there since the events should contain all information that's needed.

Can a Service Layer contain multiple services?

I'm rearchitecting a large web forms ASP.Net application, inserting a service layer to take away unwanted responsibility from the presentation layer.
I've seen a lot of examples where all the service methods are contained in one class.
Is this common / best practice? Or is it perfectly feasible to have a number of service classes within the service layer? I'm leaning towards having more than one service and those services being able to talk to each other.
Any guidance, pros/cons?
Richard
P.s. Note that I'm not talking about a web service layer, WCF or otherwsie, although that might become more relevant at a later date.
The SOLID principles, specifically the Single Responsibility Principle would suggest that having all of your functionality in one object is a bad idea, and i tend to agree. As your application grows the single class will become difficult to maintain.
Your comments to Yuriys answer would suggest you want to use an IOC container. Lets consider that in more detail for a moment...
The more functionality this single class contains, the more dependencies it will require. You could well end up having a constructor on the service that has a long list of parameters, simply because the class covers a lot of ground and depends on other functionality at a lower level, such as logging, database communication, authentication etc. Lets say a consumer of that service wants to call one, and only one specific method on that class before destroying the instance. Your IOC container will need to inject every dependency that the service could 'possibly' need at runtime, even though the consumer will only use maybe 1 or 2 of those dependencies.
Also from an operational perspective - if you have more than one developer on the team working on the service layer at the same time, there is more possibility of merge conflicts if you are both editing one file. But, as suggested you could use partials to counter that issue.
Usually a dose of practicality alongside a well known pattern or principle is the best way forward.
I would suggest researching Service Orientated Architecture if you havent already, as it may help you answer some key decisions in the approach to your solution.
Of course, it can.
Moreover, I believe that would be better to extract from this God service layer class few interfaces by functionality (i.e. ISecurityService, INotificationService etc.) and implement each interface in separate project. Also, you can utilize some IOC container to resolve class that implement service's interface. This way you can change each service's implementation independently without changing client functionality.
At least, for the first time you can mark your service super class as partial, then split it up by functionality into few .cs(.vb) files with meaningful names and group them together in Visual Studio. This will simplify navigating across service methods.
My take on structuring an application would be to start with splitting the application into two projects AppX.Web (UI logic) and AppX.Business (business logic), but still keep them in the same VS solution. The clarify in structure between business logic and UI logic helps you understand what services are shared among multiple web pages and which are local to a singel web page. You should avoid reusing code directly between the web pages, if you find that this is necessary then you should probaly move that piece of shared code to the business logic layer.
When implementing the business logic project you should try to create separate classes for different type of business logic. These classes can of course talk to eachother, but do avoid having the web pages talk to eachother.
Once you have separated UI logic from business logic you can continue to break down the AppX.Business code into smaller pieces if necessary. Common examples include:
AppX.Data: A Data Access Layer (DAL) which isolate all data manipulation from the actual business logic
AppX.Dto: Data Transfer Objects (DTO) which can be useful in many scenarios, e.g. when sending data to the client browser for processing by jQuery
AppX.Common: Shared logic which is generic to many other applications, this can be helper classes you have previously created or things which should be reviewed after the project for inclusion in company wide support classes.
Finally, let's talk about going all-in and expose your business logic as a WCF service. In that case you actually need not change anything in the existing structure. You can either add the WCF service to your existing AppX.Web project or expose them separately in AppX.Service. If you have properly separated business logic from UI logic the WCF layer can be just a thin wrapper around the business logic.
When implementing the WCF service it is quite possible to do all of that in a single class. No real business logic is available in the WCF service as it just make direct calls to the business logic.
If you build a new application you should consider you overall design up front, but now that you are rearchitecting I think you should work step-by-step:
Start by creating the AppX.Web and AppX.Business Projects
Identify services and create classes in AppX.Business for those services
Move code from the AppX.Web project into the new classes in AppX.Business, and make sure you call them from the web project.
Continue with additional break-down if you feel you need to do so!

Controllers != Business Layer?

So I'm assuming people still use a business layer outside just controller logic? If so where's that grey line drawn and what do you not put in your controller classes that you would in your Business Layer project and vice versa? Seems to me like Controllers rid the need for a business layer in your MVC application totally.
The controller layer is part of the view, in my opinion. What you're calling the business layer I call services (not web services; that's just one deployment choice among many).
The business layer knows about use cases and units of work for accomplishing the objectives of users.
The controller is all about validating, binding, and marshaling requests, determining which service is needed to fulfill the request and passing values to it, unmarshaling the response and routing it to the next appropriate view.
So I agree with the hypothesis posed in your title: controller != service.
The classic pattern that came from Smalltalk is Model-View-Controller, which disagrees with my statement by breaking view and controller into separate tiers.
What I'm describing is what is implemented in Java frameworks for both web and desktop. A change in view technology generally means changing the controller as well.
So if the Smalltalk idiom was model-view-controller, the more modern approach would look like view->controller->service->model/persistence. Model means "domain objects", which are independent of all view technologies.
The line is not "grey". It's stark and absolute.
The model (or "business layer") works with any presentation. GUI, command-line, web. And it doesn't require any changes to be wrapped with a GUI (view+control) a Command-line application or a web application.
You know you've done the model ("business layer") correctly when there are no presentation or control features in at all. Further, it's so complete that any GUI can use it directly.
To put it simply:
Controller should contain the application specific logic.
"Business Layer" should contain the business logic.
Following Eric Evans' Domain Driven Approach, the "Business Layer" contains:
Service tier: the interface is designed around the use case scenario
Domain Models: the core domain objects, entities, value objects and more.
Data Access objects: repositories
Also note that the Domain models is not the Data Access tier. It might encapsulate data access, but is not the data access tier itself.

ASP.Net MVC Architecture - Location of ViewModels

We have a decent sized MVC project running well at the moment, i've started to look at some re-factoring and I have a question.
At the moment the Data Layer and Service Layer is stored in a seperate class library. The controllers load the data objects (generated from linq2sql) from the service layer which does any logic check and then converts them to viewmodels (Using Auto-Mapper).
Instead of this should the ViewModels be returned directly from the service?
Definitely not!
A ViewModel's purpose is to mediate between the view and the 'real' data objects - it's totally view-specific. So layers other than your GUI shouldn't even know that such a model exists, if you want to keep a clean separation of concerns...
I would say not. The point of the service is that it can be used by many different projects that deal with your business layer. I would expect this to be in terms of your business objects. View models are specific to an MVC application and, thus, I would expect them to be separate from the service layer. Note that they often encompass both business and "housekeeping" data for the application, and may encapsulate multiple business objects. I think I would continue to transform them in your controller.

Using a webservice as an interface for a data access layer in .NET

I am currently doing a CRUD project for school and basically they want us to have this kind of structure (3 projects):
Class Library
Contains all the data access logic (retrieving the data from the database with either LINQ of standard ADO.NET).
Web Service
Having a reference to the class library and offering [WebMethod]s that access the methods from the class library
ASP.NET Website
Having a service reference to the web service and using the WebMethods to retrieve the data
Which basically means that we cannot access the class library directly from the website:
Website
\
\
Web Service
\
\
Class Library
Now of course there are multiple solutions to choose from as to provide abstraction in the web service to separate for example methods that retrieve the articles and methods to retrieve the categories (which are two different entiries and have two seperate classes in the class libary):
I can either do one web service which will have all the methods (GetAllArticles, GetAllCategories, GetArticleByID, etc.) and the website only makes a reference to this one web service. But of course this will result in having all the methods in a single class (that is, a single web service)
Or I can create multiple web services (Articles.asmx, Categories.asmx etc...) and reference all of them from the website and then call the one I need depending on what data I need to retrieve.
But I mean for me, the above solutions are not really ideal because if I have the first solution, I will have a ton of methods all in one class (no abstraction whatsoever) and in the second solution, I will have to reference about 10 different web services from the website (one for articles, one for categories, etc.)
At school they told us to use the web service (or web services) to access the class library, and then retrieve the data from the class library using the Webmethods, but both solutions I mentioned earlier on seem a bit dodgy.
Is there a better way of how I might go about in implementing this structure?
In your example you suggested one service for Articles and one service for Categories. That may of course be just an example, but in that case it would not make sense to separate them, because it would be quite likely and common to have queries and/or routines which make use of both Category data and Article data.
With that in mind, it usually makes the most sense to group routines by the degree to which they are related to one another. If you can separate all your possible routines into, say, three clean groups with little to no overlap, then it makes sense to have three services. If you cannot cleanly separate any of your routines, you should limit yourself to one web service.
But regarding your statement "No abstraction" being a downside of one web service - that isn't necessarily true. You can always create layers of abstraction behind the web service, so that the service class itself is simply a facade with many thin method calls that reach into bulkier logic elsewhere.
In the end, the only approach which truly matters because it's the only approach which works is this: take the simplest approach possible, only build what you need to build in as few layers as you can; only add complexity when you reach a problem which cannot be solved in a better way than by adding that complexity. It is always easier to add complexity than to take it away.
I would put all the webmethods into the same class. The webmethods should only be wrappers around you business classes plus whatever input validation and authorisation you need.
Since web services are generally used by mahcines and not humans there is no pressing need for a hierarchy. It can become a burden to manage the URLs and web server if you create a webmethod class per business class.
If you are planning on using the HTML page that browsers automatically generate to call your web services as your main user interface you need to be a little bit careful. For example you won't be able to rely on SOAP headers if you need to authenticate requests.
Why not use ADO.Net Data Service?

Resources