Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<blockquote> <p>For controllers and ViewModels, which should contain most of the business logic?</p> </blockquote> <p>None of those.</p> <blockquote> <p>I've tried a few ways to get my ViewModels to practically contain all the business logic. However, I do have to have an argument in my ViewModel's constructor that takes a Unit of Work. Is this a good idea?</p> </blockquote> <p>imho It's a very bad idea. First of all you are breaking several of the SOLID principles. Bundling all code into the view model makes it hard to test. What if you want to use some of the business logic in another view? Do you duplicate that code?</p> <blockquote> <p>What is the best practice here?</p> </blockquote> <p>Let's go back to the MVC pattern first. It's a quite wide definition but knowing it should give you a feeling of what you should place where.</p> <ul> <li><p>The "Model" in MVC is really everything that is used to pull the data together. It can be webservices, a business layer, repositories etc.</p></li> <li><p>The view is all code that generates the HTML (since we are talking about web).</p></li> <li><p>The controller should be considered to be a glue between the model and the view. Hence it should take the information from the Model and transform it into something usable by the view.</p></li> </ul> <p>The problem with that structure is that it's quite easy to "leak" layer specific information into the other parts of the pattern. Hence Microsoft introduced ViewModels into their implementation of MVC.</p> <p>In this way we can remove all rendering logic from the views and put it into the ViewModel. Instead of doing this in your view:</p> <pre><code>&lt;span&gt;@(model.Age == 0 ? "n/a" : model.Age)&lt;/span&gt; </code></pre> <p>you put that code inside the ViewModel instead and simply call <code>@model.Age</code>. In this way you don't have to duplicate that code in all views that are using your view model. </p> <p>The answer to your question about the ViewModel is that it should only contain logic which is used to render the information from the "Model" properly.</p> <p>As for the controller, I would not put any business logic into it either. First of all, it makes it very hard to test your logic. Then you add more responsibilities to it (and by doing so breaking SRP). The only logic that is valid in the controller is to take the information from the ViewModel and transform it into something usable by the "Model" and vice versa.</p> <p>Hope that answers your question.</p> <p><strong>Update</strong></p> <p>I would create a separate project and add classes to it. Then just add a reference from your webproject and call those classes in the controllers. </p> <p>I would also start using an inversion of control container to get those dependencies created for me automagically.</p> <p><a href="http://code.google.com/p/autofac/">Autofac</a> can both discover your services for you (zero-configuration) and inject itself into MVC.</p> <p>To follow the separated interface pattern create the following projects:</p> <ul> <li>YourProject.BusinessLayer &lt;-- Add your classes here</li> <li>YourProject.BusinessLayer.Specification &lt;-- Add you interfaces that defines your business layer here.</li> <li>YourProject.Mvc &lt;-- The MVC project.</li> </ul> <p>The "Specification" project can be used to make it easier to test things and to make it easier to switch implementation (might be only a few classes and not necessarily the entire business layer). Read up on "Seperated Interface Pattern"</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload