2011-06-14 21 views
19

Entiendo que MVC tiene que ver con poner 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.Dónde debería poner mi lógica de negocios de controlador en MVC3

¿Hay alguna convención sobre dónde debería ubicar 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(); 
    } 
+0

Compruebe esta pregunta relacionada: http://stackoverflow.com/q/3131798/64096 –

Respuesta

26

El lugar recomendado para poner la lógica de negocio es en una capa de servicio. De modo que podría definir una interfaz que represente la operación comercial:

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

y luego tenga 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 configura su infraestructura DI para pasar la implementación adecuada del servicio al controlador.

Observación: En el ejemplo proporcionado, utilicé AutoMapper para convertir un modelo de dominio en un modelo de vista que se pasa a la vista.

+2

este código tiene una dependencia de AutoMapper por lo que el OP puede necesitar saber acerca de esa referencia – stack72

+1

@ stack72, buen punto. He actualizado mi respuesta para proporcionar una referencia. –

+0

Gracias por su comentario. ¿Cuáles son las convenciones de nombres de archivos y directorios que utiliza para su capa de servicio? ¿Puedo asumir que conserva estos archivos en un directorio llamado Interfaces? – Geraldo

5

Lo que suelo hacer en mis proyectos MVC es mantener la mayor cantidad de la lógica de negocio como sea posible fuera de mis acciones para que yo los puedo probar

En algunos casos se crea una capa de servicio y luego usar esa

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 a ser probados por separado de mi capa de servicio y sin dependencia

esperanza esto ayuda

Paul

+0

Gracias por su comentario. ¿Cuáles son las convenciones de nombres de archivos y directorios que utiliza para su capa de servicio?Si no te importa, podrías mostrarme qué archivo típico contiene una clase que implementa IServiceLayerClass. Solo el caparazón del archivo y tal vez un argumento que se transfiere hacia adentro o hacia afuera. Muchas gracias. – Geraldo

+0

He actualizado mi respuesta para mostrar un ejemplo de clase de capa de servicio - esta clase interactúa con un servicio web pero demuestra la prueba de concepto – stack72

+0

@ stack72 - ¿Cómo se llama al controlador con la clase de servicio correcta? – Geraldo

1

La lógica empresarial debe vivir en su modelo de dominio separado del framework MVC y otras cosas.

ejemplo del mundo real ...

Aplicación (uno de mis entidades de dominio) del controlador:

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

aplicación propia entidad:

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 obtener más información sobre esta Es posible que desee compruebe de qué se trata domain driven design.

+0

@Amis - Entonces, normalmente coloca la entidad de la aplicación en algún tipo de directorio de servicio ? ¿Cómo funciona FindApplication? – Geraldo

+0

@Geraldo Mi entidad de aplicación vive en un ensamble separado llamado 'Dominio' (que solo conoce el framework .Net), carpeta' Modelo'. FindApplication simplemente llama a NHibernate directamente. –

+0

pero si el dao se usa en la capa lógica, ¿debería inyectar daoservice en el modelo? –

Cuestiones relacionadas