I'm coming from a WebForms world where all logic is located in the codebehind of the aspx-pages. After reading a few books on ASP.NET MVC, listening to some podcast and watching some videos on Tekpub, I've decided that it is time to approach things a bit differently.
Unfortunately, I'm already stuck.
I'm trying to build some sort of small and basic CMS in which I can add multiple websites.
I know I should keep my controllers thin, so I guess I should use some sort of service class (let's call it WebsiteService) to do this. I'm using Entity Framework for data access and my Views all use specific ViewModels. When I Create or Edit a Website, these four things should happen:
- Validate the input
- Add information about the Website to the database (Update information if it's an Edit)
- Create a directory on disk (Possibly rename the directory if it's an Edit)
- Add a host header to an IIS Website (Possible remove the old host header and a new one if it's an Edit)
Basically, I guess the WebsiteService should perform more advanced validation, write to the database, create/edit a directory, add/remove host headers and return something to the controller to indicate if it succeeded or not.
What should this class look like? I have a few questions to which I don't know the answer.
- Should the WebsiteService also translate the CreateWebsite ViewModel to the actual Website class or should something else do this so that the WebsiteService accepts an actual Website object?
- Basic input validation is done by using Validation attributes on the ViewModel. More extensive validation ("Is there already a Website with this domain name in the database?") should also be done. Should the WebsiteService do this as well?
- Should all 3 steps (save to database, create directory, add host header to IIS) be done in one public method (
WebsiteService.SaveWebsite(ViewModels.CreateWebsite website)
) or should I provide separate methods which the controller has to call? (I guess not because I suppose the call order is important.)
The answers to this is partially subjective, matter of opinion, but here are my thoughts:
It could. But a better approach would be to use AutoMapper to do this for you. One of the "must have" open source tools for data-driven MVC applications.
Yes - input validation should be done via validation attributes on the View Models. More extensive/domain/business validation can either be done in the service, or on the domain models themselves. I prefer (and use) the second option. My domain models are also my POCO's (used by EF), but i have extra methods/properties specific to the domain (but not the database).
No, i think this should be in seperate methods, mainly for testability/seperation of concerns. You've got three things going on - database persistence, file writing and IIS work. That to me should be three different services. I would have your "WebsiteService" delegate these tasks to other services.