Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Where should I put my controller business logic in MVC3

Tags:

asp.net-mvc

I understand MVC is all about putting things in the correct place and the logic where it should be. My controller actions are getting filled up with business logic (not related to data storage) and I feel that I should start moving some of the logic to a different place.

Is there a convention for where I should place this logic? For example I have the following controller that's located in the controllers file:

adminPowerController 

  public ActionResult Create(string test1)
    // business logic
    // business logic
    // business logic
    return View();
  }
  public ActionResult Index(string test1)
    // business logic
    // business logic
    // business logic
    return View();
  }
like image 778
Geraldo Avatar asked Jun 14 '11 09:06

Geraldo


People also ask

Where do you put your business logic typically?

Business logic should live in the data model. And, what's more, it should live in the graph data model because that's the right abstraction for the next twenty years. If you've been paying attention to this blog or to Stardog generally, then you must have known this is where we were going to end up.

Should business logic go in controller?

Let me tell you this, controllers shouldn't do anything remotely related to business logic, and directly access data stores. The controller's only purpose is to receive a request and return a response. Everything that goes in between is not its responsibility.

Can we write logic in controller?

You can start with Use of Service Layer stack overflow or Implementing Business Logic from docs.oracle.com. Now, if we look at both ways mentioned in your question, then it represents that in the first case "write business logic in Controller" is not the way you should go.

What should go in a controller MVC?

A controller is responsible for controlling the way that a user interacts with an MVC application. A controller contains the flow control logic for an ASP.NET MVC application. A controller determines what response to send back to a user when a user makes a browser request.


3 Answers

The recommended place to put business logic is into a service layer. So you could define an interface which will represent the business operation:

public interface IMyService
{
    DomainModel SomeOperation(string input);
}

and then have an implementation of this service. Finally the controller will use it:

public class MyController: Controller
{
    private readonly IMyService _service;
    public class MyController(IMyService service)
    {
        _service = service;
    }

    public ActionResult Create(string input)
    {
        var model = _service.SomeOperation(input);
        var viewModel = Mapper.Map<DomainModel, ViewModel>(model);
        return View(viewModel);
    }
}

and configure your DI framework to pass the proper implementation of the service into the controller.

Remark: In the example I provided I used AutoMapper to convert between a domain model into a view model which is passed to the view.

like image 173
Darin Dimitrov Avatar answered Oct 06 '22 10:10

Darin Dimitrov


What i tend to do in my MVC projects is to keep as much of the business logic as possible outside of my actions so that I can test them

In some cases I create a service layer and then use that

public class QuizRunner : IQuizRunner
{
    private readonly IServiceProxyclient _quizServiceProxy;
    public QuizRunner(IServiceProxyclient quizServiceProxy)
    {
        _quizServiceProxy = quizServiceProxy;
    }

    public GameCategory GetPrizeGameCategory(int prizeId)
    {
        return _quizServiceProxy.GetGameCategoryForPrizeId(prizeId);
    }

}

public interface IQuizRunner
{
    GameCategory GetPrizeGameCategory(int prizeId);
}



private IQuizRunner_serviceClass;

public AdminPowercontroller(IQuizRunner serviceClass)
{
    _serviceClass = serviceClass;
}


public ActionResult Create(string test1)
    var itemsFromLogic = _serviceClass.Method1();
    return View();
}
public ActionResult Index(string test1)
    var gameCategory = _serviceClass.GetPrizeGameCategory(test1);
    var viewModel = Mapper.Map<GameCategory, GameCategoryViewModel>(gameCategory);
    return View(viewModel);
}

this allows my actions to be tested separately from my service layer and without dependency

Hope this helps

Paul

like image 42
stack72 Avatar answered Oct 06 '22 08:10

stack72


Business logic should live in your domain model separated from MVC framework and other stuff.

Real world example...

Application (one of my domain entities) controller:

[HttpPost]
public ActionResult Withdraw(int applicationId){
  //find it from repository or whatever
  var app=FindApplication(applicationId);
  //force it do do stuff
  a.Withdraw();
  //send back some response
  return RedirectToAction("Application",new{applicationId});
}

Application entity itself:

public class Application{
 public void Withdraw(){
  //check if current user is authorized to withdraw applications
  Authorize<CanWithdrawApplications>();
  //check if application itself can be withdrawn
  ThrowIf(!CanBeWithdrawn(),"Application can't be withdrawn.");
  //apply state changes
  IsWithdrawn=true;
  //raise domain event
  Raise(new Withdrawn(this));
 }
 public bool CanBeWithdrawn(){
   return !IsWithdrawn && !Project.Contract.IsSigned;
 }
}

For more about this You might want to check out what domain driven design is about.

like image 1
Arnis Lapsa Avatar answered Oct 06 '22 10:10

Arnis Lapsa