Architecting ASP.net MVC App to use repositories and services - asp.net-mvc

I recently started reading about ASP.net MVC and after getting excited about the concept, i started to migrate all my webform project to MVC but i am having a hard time keeping my controller skinny even after following all the good advices out there (or maybe i just don't get it ... ).
The website i deal with has Articles, Videos, Quotes ... and each of these entities have categories, comments, images that can be associated with it. I am using Linq to sql for database operations and for each of these Entities, i have a Repository, and for each repository, i create a service to be used in the controller.
so i have -
ArticleRepository
ArticleCategoryRepository
ArticleCommentRepository
and the corresponding service
ArticleService
ArticleCategoryService ...
you see the picture.
The problem i have is that i have one controller for article,category and comment because i thought that having ArticleController handle all of that might make sense, but now i have to pass all of the services needed to the Controller constructor. So i would like to know what it is that i am doing wrong. Are my services not designed properly? should i create Bigger service to encapsulate smaller services and use them in my controller? or should i have an articleCategory Controller and an articleComment Controller?
A page viewed by the user is made of all of that, thee article to be viewed,the comments associated with it, a listing of the categories to witch it applies ... how can i efficiently break down the controller to keep it "skinny" and solve my headache?
Thank you!
I hope my question is not too long to be read ...

This is the side effect of following the Single Responsibility Pattern. If each class is designed for only one purpose, then you're going to end up with a lot of classes. This is a good thing. Don't be afraid of it. It will make your life a lot easier in the long run when it comes to swapping out components as well as debugging which components of your system aren't working.
Personally, I prefer putting more of my domain logic in the actual domain entities (e.g. article.AddComment(comment) instead of articleCommentService.AddComment(article, comment)), but your approach is perfectly fine as well.

I think you are headed in the right direction. The question is how to instantiate your services? I'm no MVC.NET guru, but have done plenty of service oriented Java projects and exactly the pattern you are discussing.
In Java land we would usually use Spring to inject singleton beans.
1) You can do the same thing in .NET, using dependency injection frameworks.
2) You can instantiate services as needed in the method, if they are lightweight enough.
3) You can create static service members in each controller as long as you write them to be threadsafe, to reduce object churn. This is the approach I use in many cases.
4) You can even create a simple, global service factory that all controllers access, which could simply be a class of singletons.
Do some Googling on .NET dependency injection as well.

Related

Where should I add a List All Users function when using MVC?

I'm aware that in model-view-controller, the Model is the class part.
If I have a User class and instantiate an object, the object must refer to a single user from the database.
So I'll have the CRUD methods on the user, for that specific user.
But if I need a function to run a SELECT * FROM Users, should I create a function within the User class? Or a function in a helper file? Or in the controller? Where should it go, in order to respect the MVC pattern?
I mean, it makes no sense to instantiate a User object just to run a function to display the Users table.
I'm not sure if this will raise "primarily opinion based" flags. I just don't know where those functions should go. If you guys consider the question worth closing, it's ok. But tell me in the comments in which stack community I should ask this.
Back up a bit. Let's go foundational for a moment.
In the MVC pattern
The model is your state (in simple terms), meaning a representation of the data important to the business functionality you are working with
The view is a way of presenting the state to the user (NOTE user here could be another system, as you can use MVC patterns for service endpoints)
The controller ensures the model gets to the view and back out of the view
In a system designed with good separation of state, business functions are not present in the model, the view or the controller. You segregate business functionality into its own class library. Why? You never know when the application will require a mobile (native, not web) implementation or a desktop implementation or maybe even become part of a windows service.
As for getting at data, proper separation of concerns states the data access is separate not only from the model, view and controller, but also from the business functionality. This is why DALs are created.
Before going on, let's go to your questions.
should I create a function within the User class? This is an "active record" pattern, which is largely deprecated today, as it closely couples behavior and state. I am sure there are still some instances where it applies, but I would not use it.
Or a function in a helper file? Better option, as you can separate it out. But I am not fond of "everything in a single project" approach, personally.
Or in the controller? Never, despite Scott Gu's first MVC examples where he put LINQ to SQL (another groan?) in the controller.
Where should it go, in order to respect the MVC pattern?
Here is my suggestion:
Create a DAL project to access the data. One possible pattern that works nicely here is the repository pattern. If you utilize the same data type for your keys in all/most tables, you can create a generic repository and then derive individual versions for specific data. Okay, so this one is really old, but looking over it, it still has the high level concepts (https://gregorybeamer.wordpress.com/2010/08/10/generics-on-the-data-access-layer)
Create a core project for the business logic, if needed. I do this every time, as it allows me to test the ideas on the DAL through unit tests. Yes, I can test directly in the MVC project (and do), but I like a clean separation as you rarely find 0% business rules in a solution.
Have the core pull the data from the DAL project and the MVC project use the core project. Nice flow. Easy to unit test. etc.
If you want this in a single project, then separate out the bits into different folders so you can make individual projects, if needed, in the future.
For the love of all things good and holy, don't use the repository pattern. #GregoryABeamer has a great answer in all respects, except recommending you create repository instances to access your entities. Your ORM (most likely Entity Framework) covers this, and completely replaces the concepts of repositories and unit of work.
Simply, if you need something from your database, hit your ORM directly in your controller. If you prefer, you can still add a level of abstraction to hide the use of the ORM itself, such that you could more easily switch out the data access with another ORM, Web Api, etc. Just don't do a traditional unit of work with tens or hundreds of repository instances. If you're interested, you can read a series of posts I wrote about that on my blog. I use the term "repository" with my approach, but mostly just to contrast with the typical "generic" repository approach you find scattered all over the interwebs.
I'd use some kind of 'Repository' layer. Then, my controller calls the UserRepository GetAll method and sends the data to View layer.

Implementing application logic on model layer (MVC)

I keep reading that the biggest layer in the MVC pattern should be the model. I've also heard that we should avoid putting logic on the controller layer. However, as my ASP.Net MVC 5 application is getting larger, I see that I'm getting heavy views, heavy controllers, and... extremely tiny models (they're not more than references to my SQL tables).
Yes, I admit, I could never manage to put any logic on my model.
I like the MVC pattern, and my website is working good, but I keep on thinking that I'm surely not doing things right...
Can you show me some useful links about how to write MVC code properly? Rick Anderson's (Microsoft) MVC 5 tutorial is fine, but once again, his models are indeed very tiny...
In my applications I put as much logic as possible in the domain models. On top of that there is an application layer which interacts with the database and domain models to perform application specific operations. The controller actions have as little code as possible and just call methods in the application layer.
In addition I usually have a view model for each view. Any logic that you have making your views "heavy" would go there.
One of the main reasons I try to put as much logic as possible in the domain models is to make unit testing easier. Logic in the application layer usually involves the database, which you will need to mock in order to test. Moving logic to the domain models makes testing easier and makes you code more reusable.
This is a pretty complex issue. I have an in depth blog post on the question if you're interested.
This answer is also pretty close to what I would suggest.
You're missing a service/business layer which should be injected in your controllers though "Dependency Injection". These services do all the heavy lifting.
Having Models without any methods or operations in them is a good thing. You're only storing this info anyway. They basically just get; set; data.
Use extra layer between models and controllers (for example repositories as data access layer).
I strongly recommend using ViewModels-they make code much more organized.
You should Create Some Classes that purely doing business logic and emit ViewModels for MVC view. Controller should respond to actions and the action method delegate the responsibility of getting the model to this business classes.
After some research on this issue, and taking into account some of these answers and comments, I realized that a medium sized MVC project can't rely exclusively on the 3 layered model. As the controller actions become bigger, the developer starts feeling the need of creating a 4th layer: the service layer. Like Gunnar Peipman correctly suggests in the following blog post, "Controller communicates with service layer and gets information about how access code claiming succeeded": http://weblogs.asp.net/gunnarpeipman/archive/2011/06/20/asp-net-mvc-moving-code-from-controller-action-to-service-layer.aspx

ASP.NET MVC Data Access Layer

I'm working on an ASP.NET MVC project. In my solution I have the following projects:
BlogApp.Web (ASP.NET MVC app),
BlogApp.Data (Class Library)
I'm wondering how to implement data access layer. I want to use EntityFramework Code First approach. I was thinking about Repository pattern, but is this really necessary? I have read that it is only the next layer on top of ORM, which isn't really needed. So instead of writing method like:
GetAllPosts(Tag t) {
db.Posts.Where(p => p.Tags.Contains(t)).Skip(x).Take(y).Select(p => p);
}
I create db context in controller and write the same query? I don't need to implement paging and write wrappers around my models.
What you may have heard about the Repository pattern is that it's falling out of favour in some camps - see for instance Jimmy Bogard's blog. This doesn't mean that queries should be written directly in controllers, unless your application is very, very simple.
As has been noted, your queries should be written in only one place which your controller can then use - this would either be in a Repository method or in a dedicated Query Object, both of which provide better abstraction and avoid duplication.
Regarding simplicitly - is your application intended to have multiple front-ends which will require a separate assembly for your data access layer? If not you might want to consider merging the two assemblies and just using namespaces to keep things organised.
Not sure whether this question belongs here.
Anyway, if you write data access logic in your controller, and the same logic is required in another controller, what would you do? Copy-Paste this into new controller? That's just not good. Anytime, you are copying and pasting you need to step back, there must be something wrong here (aka code smell).
Separating the logic into different layer will make your code more maintainable and testable. Trust me!

When should I consider implementing a Service in Grails?

I'm new to Grails and web development. I started doing a project on Schedule management website stuff. I came across the Service concept that is provided by Grails. I understood the concept, but still I have confusion on when to use services.
For example, I need to implement a search module, where the manager can search for a user to find his schedules. In this case it will be good to implement it as a controller or as a service?
So,
When and where should I use Service?
To add to Grooveek's answer;
It is also nice to use Services to keep your Controllers nice and clean.
So Views just render data to the screen, Domain objects store state, Controllers route the user around the application, and Services perform the work.
I don't have enough reputation to comment on an answer or vote up so I have to provide an answer that really should be a comment. Anyways...
+1 on #tim_yates answer. Gotta love thin controllers. 2 things that I would add to the description of a controller:
Would be to translate parameters from the browser before hitting a service (e.g. Date, number, etc.)
Would be to translate data returned from services into something consumable for the views.
For me, ideally, services would never deal with translating a String parameter to it's inherent type. Or deal with building a model to be displayed on a view.
What and where I should use Service?
When you want your controller do to something that may be reused by other controllers
In our application we're doing a functional separation of service. We have a CorePersistanceService, which provides method to create, delete, update and manipulate Core Domain Classes (core for us).
I think persistance services are a good way to reuse GORM code throughout Grails code. You can create method in domain classes, but I don't like that, it's way less maintanable I think
We have a PDFService class for our PDF creation, a SolrService which connect to Solr, a Statisticservice that gather all our methods which collects statictics on our datas
Services in Grails are a manner to gather methods around a particular functional theme, in order to give possibility to reuse them in controllers (I forgot to mention our SecurityService, which is a pretty good Cross-Applications Example)

MVC DDD: Is it OK to use repositories together with services in the controller?

most of the time in the service code I would have something like this:
public SomeService : ISomeService
{
ISomeRepository someRepository;
public Do(int id)
{
someRepository.Do(id);
}
}
so it's kinda redundant
so I started to use the repositories directly in the controller
is this ok ? is there some architecture that is doing like this ?
You lose the ability to have business logic in between.
I disagree with this one.
If business logic is where it should be - in domain model, then calling repo in controller (or better - use model binder for that) to get aggregate root and call method on it seems perfectly fine to me.
Application services should be used when there's too much technical details involved what would mess up controllers.
I've seen several people mention using model binders to call into a repo lately. Where is this crazy idea coming from?
I believe we are talking about 2 different things here. I suspect that Your 'model binder' means using model simultaneously as a view model too and binding changed values from UI directly right back to it (which is not a bad thing per se and in some cases I would go that road).
My 'model binder' is a class that implements 'IModelBinder', that takes repository in constructor (which is injected and therefore - can be extended if we need caching with some basic composition) and uses it before action is called to retrieve aggregate root and replace int id or Guid id or string slug or whatever action argument with real domain object. Combining that with input view model argument lets us to write less code. Something like this:
public ActionResult ChangeCustomerAddress
(Customer c, ChangeCustomerAddressInput inp){
c.ChangeCustomerAddress(inp.NewAddress);
return RedirectToAction("Details", new{inp.Id});
}
In my actual code it's a bit more complex cause it includes ModelState validation and some exception handling that might be thrown from inside of domain model (extracted into Controller extension method for reuse). But not much more. So far - longest controller action is ~10 lines long.
You can see working implementation (quite sophisticated and (for me) unnecessary complex) here.
Are you just doing CRUD apps with Linq To Sql or trying something with real domain logic?
As You can (hopefully) see, this kind of approach actually almost forces us to move towards task based app instead of CRUD based one.
By doing all data access in your service layer and using IOC you can gain lots of benefits of AOP like invisible caching, transaction management, and easy composition of components that I can't imagine you get with model binders.
...and having new abstraction layer that invites us to mix infrastructure with domain logic and lose isolation of domain model.
Please enlighten me.
I'm not sure if I did. I don't think that I'm enlightened myself. :)
Here is my current model binder base class. Here's one of controller actions from my current project. And here's "lack" of business logic.
If you use repositories in your controllers, you are going straight from the Data Layer to the Presentation Layer. You lose the ability to have business logic in between.
Now, if you say you will only use Services when you need business logic, and use Repositories everywhere else, your code becomes a nightmare. The Presentation Layer is now calling both the Business and Data Layer, and you don't have a nice separation of concerns.
I would always go this route: Repositories -> Services -> UI. As soon as you don't think you need a business layer, the requirements change, and you will have to rewrite EVERYTHING.
My own rough practices for DDD/MVC:
controllers are application-specific, hence they should only contain application-specific methods, and call Services methods.
all public Service methods are usually atomic transactions or queries
only Services instantiate & call Repositories
my Domain defines an IContextFactory and an IContext (massive leaky abstraction as IContext members are IDBSet)
each application has a sort-of Composition Root, which is mainly instantiating a Context Factory to pass to the Services (you could use DI container but not a big deal)
This forces me to keep my business code, and data-access out of my controllers. I find it a good discipline, given how loose I am when I don't follow the above!
Here is the thing.
"Business Logic" should reside in your entities and value objects.
Repositories deal with AggregateRoots only. So, using your repositories directly in your Controllers kinda feels like you are treating that action as your "service". Also, since your AggregateRoot may only refer to other ARs by its ID, you may have to call one more than one repo. It really gets nasty very quickly.
If you are going to have services, make sure you expose POCOs and not the actual AggregateRoot and its members.
Your repo shouldn't have to do any operations other than creating, retrieving, updating and deleting stuff. You may have some customized retrieve based on specific conditions, but that's about it. Therefore, having a method in your repo that matches one in your service... code smell right there.
Your service are API oriented. Think about this... if you were to pack that service in a .dll for me to use, how would you create your methods in a way that is easy for me to know what your service can do? Service.Update(object) doesn't make much sense.
And I haven't even talked about CQRS... where things get even more interesting.
Your Web Api is just a CLIENT of your Service. Your Service can be used by another service, right? So, think about it. You most likely will need a Service to encapsulate operations on AggregateRoots, usually by creating them, or retrieving them from a repo, do something about it, then returning a result. Usually.
Makes sense?
Even with "rich domain model" you will still need a domain service for handling business logic which involves several entities. I have also never seen CRUD without some business logic, but in simple sample code. I'd always like to go Martin's route to keep my code straightforward.

Resources