MVC: Should logic be placed in the Model or Service layer? - model-view-controller

Recently I talked with a co-worker and had a conversation regarding Model View Controller paradigm. We were talking about proper organization of files and such and I mentioned that I thought that "skinny controllers and fat models" were the way to go. Meaning that the controller just calls the "fat models" methods which contain business logic:
public class CreditCard {
//instance vars
//constructor
//getters
//setters (if you want mutability)
public boolean makeCreditCardPayment(Cart cart) {
//implementation details...
}
}
My co-worker mentioned otherwise. He said that the models shouldn't really be "fat" and contain any other business logic. The model should just be a data-structure and contain zero methods (obviously if your are in Java you need setters and getters). Just like a C-style structure, obviously with data fields that have mutators and accessors:
public class CreditCard {
//instance vars
//constructor
//getters
//setters (if you want mutability)
}
public class PaymentService {
public boolean makeCreditCardPayment(CreditCard card, Cart cart) {
//implementation details...
}
public boolean makePayPalPayment(PayPal paypal, Cart cart){
//implementation details...
}
Or even have a PaymentService for each type of payment that implements an interface. So something like 'CreditCardPaymentService implements Payment' or 'PayPalPaymentService implmeents Payment'.
To me, using the service method way seems like we are just going back to procedural style programming.
Another example would be a 'Vehicle' object with a getSpeed method compared to a service which takes in a Vehicle object and returns the speed.
I have looked over other stackoverflow answers but they have differing answers. In one question, one of the users mentioned that the service layer is part of the models part of MVC. I am looking for other answers.

I've encountered many different philosophies claimed to fall under the MVC umbrella.
My position:
Models directly manage some kind of backing store, and should contain mutation and validation logic.
Controllers should look like a model to other controllers and views (making them composable), and contain any additional logic required to validate the mapping from the controller's interface to a model's interface.
Views just contain whatever state and logic they need to function; their purpose is to display data and collect input.
It looks like your PaymentService is trying to be more than one controller, so I'd go the separate CreditCardPaymentService and PayPalPaymentService route.

Related

Unit testing store procedure calls with Entity Framework

I need to add unit tests and increase code coverage of an application that is based o store procedure calls using Entity Framework.
Example 1:
public virtual DbSet<Person> Persons { get; set; }
public virtual IEnumerable<Person> PersonsFromSP()
{
return Persons.SqlQuery("spGetPersons").ToList();
}
Example 2:
public virtual IEnumerable<Animal> AnimalsFromSP()
{
return Database.SqlQuery<Animal>("spGetAnimals").ToList();
}
There's also code with business logic and other stuff, but it's all based on these calls.
Whats a good approach at testing this?
Thanks in advance.
I tried describing our approach in another answer: here.
Basically, you need to have an interface that your Context class will implement. The methods of the Context class will not be tested during unit testing because of the coupling to the database. However, you can test other classes (the business logic) that will reference the interface and not the concrete implementation.
The linked answer contains one detail of implementing the interface. We had two properties, only one of which was defined in the interface (AccountContacts in the example). The AccountContacts property will then relay the calls to the concrete implementation.
In your case, your Persons property will be the property that the clients of the Context will use. Then you can have another property, DbPersons that will actually be filled by the stored procedure.

Domain driven design - access modifiers for entities and enforcing validation

I am very new to DDD and reading various discussions on validation (where to put it) on the stackoverflow as well as on the web. I do like the idea of keeping the validations outside the entities and validate them depending upon the context. In our project, we have an entity called MedicalRecord and there are various rules for when one can be created or can be saved. I want to create a service layer, let's say RecordService, that would do some check to make sure if a user can create a medical record before creating one. I also want to create MedicalRecordRepository that would save the medical record. What confuses me is the access modifies on my entity and repository classes. Since both will be public, how can I enforce the client of my application to use the service instead of just creating new medical record (with public constructor) and use the repository to save it? I am using c#. I know DDD is language independent but wondering if someone could provide some thoughts on this.
Thanks.
You must control record creation by making the c'tor non-public and allowing creation only through a factory:
public class MedicalRecord
{
internal MedicalRecord()
{
}
}
public static class MedicalRecordFactory
{
public static MedicalRecord Create(User onBehalfOf)
{
// do logic here
return new MedicalRecord();
}
}
For the internal keyword to be applicable, either both classes must be in the same assembly or the class assembly must allow the factory assembly access with the InternalsVisibleTo attribute.
Edit
If you need to be able to perform validation at any time, you additionally have to encapsulate validation logic in another class (here partially done via an extension method):
public static class MedicalRecordValidator
{
public static bool IsValid(this MedicalRecord medicalRecord, <context>)
{
return IsValid(<context>);
}
public static bool IsValidForCreation(User onBehalfOf)
{
return IsValid(null, onBehalfOf);
}
private static bool IsValid(<context> context, User user = null)
{
// do validation logic here
}
}
then, the factory could do this:
public static MedicalRecord Create(User onBehalfOf)
{
return IsValidForCreation(onBehalfOf) ? new MedicalRecord() : null;
}
and you could also always do this:
if (myMedicalRecord.IsValid(<context>))
{
// ....
Only use your repository to retrieve your entities; not to save them. Saving (persisting) your entities is the responsibility of your unit of work.
You let your service change one or more entities (for instance a MedicalRecord) and track the changes in a unit of work. Before committing the changes in your unit of work, you can validate all entities for validation needs across entities. Then you commit your unit of work (in a single transaction), which will persist all your changes, or none at all.
For clarity, your MedicalRecord should protect its own invariants; such that a client retrieving a MedicalRecord using a repository, calling some methods to modify it and then persisting it using a unit of work, should result in a "valid" system state. If there are situations where this is not the case, then it can be argued that it should not be possible to retrieve a MedicalRecord on its own - it is part of some larger concept.
For creation purposes, using a factory like #Thomas suggests below is a good approach, although I think I'd call it a service (because of the collaboration between entities) instead of a factory. What I like about Thomas' approach is that it does not allow a client to create a MedicalRecord without a User (or other contextual information), without tying the MedicalRecord tightly to the user.

MVC design pattern model logic

According to the MVC design pattern, if we create a user (database work) and we have to send a mail with an activation code to the user, would this fit in the model or in the controller, after the model created the database record?
The MVC pattern is used to create an abstraction between the business logic (the model) and the GUI (the view). The controller is just an adapter (google adapter pattern) between those two blocks.
Hence the controller should only have code which is used to fetch the required information from the controller and adopt it so it fits the view. Any other logic should be in the model.
That only make sense if you understand that the model is not a single class but all of your business logic.
Example (implementation specific, but I hope that you understand):
public class UserController : Controller
{
// notice that it's a view model and not a model
public ActionResult Register(RegisterViewModel model)
{
UserService service;
User user = service.Register(model.UserName);
return View("Created");
}
}
// this class is located in the "model"
public class UserService
{
public User Register(string userName)
{
// another class in the "model"
var repository = new UserRepository();
var user = repository.Create(userName);
// just another "model" class
var emailService = new EmailService();
emailService.SendActivationEmail(user.Email);
return user;
}
}
MVC and MVC-inspired design patterns are combination of two layers:
Presentation layer
Model layer
Presentation layer is made up from views, controllers and (mostly in web-oriented solutions) templates. This layer deals with user interaction. It recognizes user input, produces responses and governs other aspect of user interface. The controllers, based on user interaction, change the state of model layer.
The model layer deals with domain business rules and interacts with different forms of storage. Model layer, just like presentation layer, is no any single object or class, but a group of structures with different responsibilities.
In this case, it would make sense for the service, which deals with user management, to use the different structures, that would both send the verification email, create an account and store this newly created user.
Services in model layer act like the barrier, that isolated the presentation layer from business logic. They deal with interaction between domain objects and storage abstractions (data mappers, repositories, units of work, etc.).
TL;DR
Email, with activation code for the newly created user, should be sent from model layer.
The controller is an object which simplifies and delegates messages to the model objects.
What you will have is an Interface object (or boundary object) within your model that represents the link between two systems (your system and email). class EmailClient. Your model objects will collaborate with this object when required.

MVC3 - EF4: One DbContext for all Repositories and ViewModels - UnitOfWork?

I'm totally stuck.
I've got two Controller: "Customer" and "Address". Both have the fields CustomerRepository and AddressRepository.
There are two ViewModels: CustomerViewModel and AddressViewModel. They also have the fields CustomerRepository and AddressRepository. (And also a parameterless constructor since they are parameters within the edit and create methods)
The Repositories themselves have a DbContext object from my Entities.
Now I'm running into one problem after another. I think I should have only ONE DbContext to share with all of my classes (Repositories AND ViewModels). And I think UnitOfWork is the solution. But I have no clue how to use that.
I currently tried to create a DbContext within the controllers constructor and pass it to every single object requiring it. But even that doesn't work.
If code is necessary, I will post it.
Couple of things to know:
1. Unit of Work
Unit of Work is not necessarily some kind of implementation for IUnitOfWork. It is just a pattern that might be applied in many ways. First, and foremost - you should understand what is it for before actually using it and overcomplicate things around. Moreover, EF Code-First DbContext API's DbContext is a kind of Unit of Work pattern. Your IDbSet<>s are your repositories. Don't try to abstract from your ORM, start with simplest possible thing.
2. DbContext injection
For the beginning, just inject the DbContext to your Controller with constructor injection. Don't forget to setup the IoC container of choice and wire up the MVC's DependencyResolver. Your controller could be look like (example also contains AutoMapper usage example, see next point about ViewModels for that):
public CustomerController : Controller
{
public CustomerController(MyDbContext data, IMappingEngine mapper)
{
Data = data;
Mapper = mapper;
}
public MyDbContext Data { get; set; }
public IMappingEngine Mapper { get; set; }
// Other controller code
}
3. View Models
This, again, is a pattern that is so easily implementable - just have your CustomerViewModel and use AutoMapper to easily transform your Customer to CustomerViewModel so that you can do it like this:
public ActionResult Details(int id)
{
var customer = Data.Customers.FirstOrDefault(c => c.Id == id);
if (customer == null)
return new HttpNotFoundResult();
return View(Mapper.Map<CustomerViewModel>(customer));
}
You can interrogate the AutoMapper's website on how to wire it up and make it running.
Notice that you don't get the ViewModel from DbContext directly. You obtain an "entity" instead which then transformed to appropriate View Model.
Hope this helps!
Your ViewModels should not have references to the DbContext or repositories. ViewModels should be largely stupid. It is the job of the controller (or a service called by the controller) to populate the ViewModels with the data the View needs.
Unit Of work is a good pattern, and one you should use.. but the patern is not a fix for your problem. Your problem is that you are making your view have too much knowledge of your data model.
I currently do the following:
One injected IUnitOfWork using unity to inject into my controllers.
IUnitOfWork implements IContext.
IContext contains IDbSet Customers and IDbSet
The concrete implementation of IContext implements DbContext.
My controllers reference a service, the service uses the IUnitOfWork.
If you use a repository, then simply use a single IContext injected into your controller (or IUnitOfWork which is fairly easy to add on top)
This way I have one context per lifetime of the request and then it's disposed. If you want more code let me know I'll see what I can post up here.

Spring MVC 3 - Binding an 'immutable' object to a form

I have several thoroughly unit-tested and finely crafted rich DDD model classes, with final immutable invariants and integrity checks. Object's instantiation happens through adequate constructors, static factory methods and even via Builders.
Now, I have to provide a Spring MVC form to create new instances of some classes.
It seems to me (I'm not an expert) that I have to provide empty constructor and attribute's setters for all form's backing classes I want to bind.
So, what should I do ?
Create anemic objects dedicated to form backing and transfer the informations to my domain model (so much for the DRY principle...) calling the appropriate methods / builder ?
Or is there a mecanisms that I missed that can save my day ? :)
Thank you in advance for your wisdom !
The objects that are used for binding with the presentation layers are normally called view models and they are DTOs purposed toward displaying data mapped from domain objects and then mapping user input back to domain objects. View models typically look very similar to the domain objects they represent however there are some important differences:
Data from the domain objects may be flattened or otherwise transformed to fit the requirements of a given view. Having the mapping be in plain objects is easier to manage than mappings in the presentation framework, such as MVC. It is easier to debug and detect errors.
A given view may require data from multiple domain objects - there may not be a single domain object that fits requirements of a view. A view model can be populated by multiple domain objects.
A view model is normally designed with a specific presentation framework in mind and as such may utilize framework specific attributes for binding and client side validation. As you stated, a typical requirement is for a parameterless constructor, which is fine for a view model. Again, it is much easier to test and manage a view model than some sort of complex mapping mechanism.
View models appear to violate the DRY principle, however after a closer look the responsibility of the view model is different, so with the single responsibility principle in mind it is appropriate to have two classes. Also, take a look at this article discussing the fallacy of reuse often lead by the DRY principle.
Furthermore, view models are indeed anemic, though they may have a constructor accepting a domain object as a parameter and a method for creating and updating a domain object using the values in the view model as input. From experience I find that it is a good practice to create a view model class for every domain entity that is going to be rendered by the presentation layer. It is easier to manage the double class hierarchy of domain objects and view models than it is to manage complex mapping mechanisms.
Note also, there are libraries that attempt to simplify the mapping between view models and domain objects, for example AutoMapper for the .NET Framework.
Yes you will need to create Objects for the form to take all the input, and the update the your model with this objects in one operation.
But I wont call this objects anemic (especially if you do DDD). This objects represent one unit of work. So this are Domain Concepts too!
I solved this by creating a DTO Interface:
public interface DTO<T> {
T getDomainObject();
void loadFromDomainObject(T domainObject);
}
public class PersonDTO implements DTO<Person> {
private String firstName;
private String lastName;
public PersonDTO() {
super();
}
// setters, getters ...
#Override
public Person getDomainObject() {
return new Person(firstName, lastName);
}
#Override
public void loadFromDomainObject(Person person) {
this.firstName = person.getFirstName();
this.lastName = person.getLastName();
}
// validation methods, view formatting methods, etc
}
This also stops view validation and formatting stuff from leaking into the domain model. I really dislike having Spring specific (or other framework specific) annotations (#Value, etc) and javax.validation annotations in my domain objects.

Resources