vista ventajas patron mvc modelo estructura ejemplos ejemplo diseño desventajas controlador capas asp.net-mvc

asp.net-mvc - ventajas - mvc c# ejemplo



¿Dónde debería poner mi lógica de negocios del controlador en MVC3? (3)

El lugar recomendado para colocar la lógica empresarial es en una capa de servicio. Entonces, podría definir una interfaz que representará la operación del negocio:

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

y luego tener una implementación de este servicio. Finalmente el controlador lo usará:

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

y configure su marco DI para pasar la implementación adecuada del servicio al controlador.

Nota: En el ejemplo que proporcioné, utilicé AutoMapper para convertir entre un modelo de dominio en un modelo de vista que se pasa a la vista.

Entiendo que MVC tiene que ver con poner las cosas en el lugar correcto y la lógica donde debería estar. Las acciones de mi controlador se están llenando de lógica empresarial (no relacionada con el almacenamiento de datos) y creo que debería comenzar a mover parte de la lógica a un lugar diferente.

¿Hay una convención para donde debo colocar esta lógica? Por ejemplo, tengo el siguiente controlador que se encuentra en el archivo de controladores:

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


La lógica de negocios debe estar en su modelo de dominio separado del marco MVC y otras cosas.

Ejemplo del mundo real ...

Controlador de la aplicación (una de mis entidades de dominio):

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

Entidad de aplicación en sí:

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

Para más información sobre esto, es posible que desee comprobar de qué se trata el diseño impulsado por dominio .


Lo que tiendo a hacer en mis proyectos de MVC es mantener la mayor parte posible de la lógica empresarial fuera de mis acciones para poder probarlas

En algunos casos creo una capa de servicio y luego la uso

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

esto permite que mis acciones se prueben por separado de mi capa de servicio y sin dependencia

Espero que esto ayude

Pablo