我应该把我的控制器业务逻辑放在MVC3中

时间:2022-10-19 22:28:19

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.

我理解MVC就是将事物放在正确的位置和逻辑应该是什么。我的控制器操作充满了业务逻辑(与数据存储无关),我觉得我应该开始将一些逻辑移到另一个地方。

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();
  }

3 个解决方案

#1


27  

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.

并配置您的DI框架以将服务的正确实现传递到控制器。

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.

备注:在我提供的示例中,我使用AutoMapper将域模型转换为传递给视图的视图模型。

#2


5  

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

我在MVC项目中倾向于做的是尽可能多地保留业务逻辑,以便我可以测试它们

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

保罗

#3


1  

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

业务逻辑应该存在于与MVC框架和其他东西分离的域模型中。

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.

有关此内容的更多信息您可能想要查看域驱动设计的内容。

#1


27  

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.

并配置您的DI框架以将服务的正确实现传递到控制器。

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.

备注:在我提供的示例中,我使用AutoMapper将域模型转换为传递给视图的视图模型。

#2


5  

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

我在MVC项目中倾向于做的是尽可能多地保留业务逻辑,以便我可以测试它们

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

保罗

#3


1  

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

业务逻辑应该存在于与MVC框架和其他东西分离的域模型中。

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.

有关此内容的更多信息您可能想要查看域驱动设计的内容。