5

Actualmente estoy trabajando en un proyecto de MVC 3 usando Ninject como mi DI, los objetos comerciales se almacenan en un ensamblaje separado. Me encuentro con un problema con los parámetros del controlador, cuando vuelvo a publicar para las operaciones de CRUD me sale el error "No se puede crear una instancia de una interfaz". Soy consciente de que no puede crear una instancia de una interfaz, pero parece que la única manera de evitarlo es usar una carpeta de modelo personalizada y pasar la FormCollection. Esto parece realmente desordenado y quiero mantener la mayor cantidad posible de códigos de tipo del proyecto, por lo que puedo interactuar en todas partes con Ninject y resolver los concretos. No solo el encuadernado de modelo personalizado parece desordenado, ¿no perderé también mis Anotaciones de datos?Entidad que pasa MVC 3 como interfaz

algo de código para describir lo que tengo:

public ActionResult Create() 
{ 
    // I'm thinking of using a factory pattern for this part 
    var objectToCreate = new ConcereteType(); 
    return (objectToEdit); 
} 

[HttpPost] 
public ActionResult Create(IRecord record) 
{ 
    // check model and pass to repository 
    if (ModelState.IsValue) 
    { 
     _repository.Create(record); 
     return View(); 
    } 

    return View(record); 
} 

Alguien ha funcionado en esto antes? Como lo superaste?

Gracias!

Respuesta

3

Los datos pasados ​​a la acción de los controladores son simplemente titulares de valores. No debería haber ninguna lógica en ellos así que no hay nada de lo que desacoplarse. Puede utilizar los tipos concretos (por ejemplo, registro) en lugar de la interfaz (iRecord)

+1

¿No estaría yo rompiendo la regla del acoplamiento flojo? ¿Qué ocurre si quiero/tengo que cambiar el nombre de mi método concreto por alguna razón, es decir, el registro se convierte en RecordDifferent? Puedo tener RecordDifferent implementando IRecord y cambiar mi DI para ahora inyectar RecordDifferent en todos los casos de IRecord. –

+1

Prefiero usar clases para contenedores modelo y herencia en lugar de interfaces. Por defecto DI no se usa para crear objetos pasados ​​a acciones. Utilizo DI solo para la lógica real, no para los contenedores de datos. – Novakov

+0

Realmente no entendí lo que quería decir inicialmente, pero después de haber progresado un poco con este proyecto ahora me di cuenta de que estoy tratando de "desacoplar" contenedores de datos simples como usted dijo. No existe ningún comportamiento (todavía) en ninguno de los objetos POCO que mapean una tabla de base de datos y, por lo tanto, no hay razón para interactuar con ellos, ni utilizar una fábrica para crear instancias de ellos. Creo que lo que tuve problemas para entender es que el desacoplamiento debería usarse realmente para objetos con comportamiento en lugar de simplemente propiedades de datos. –

6

pero parece que la única manera que pueden evitar esto es usar un aglomerante modelo personalizado

Un aglutinante modelo personalizado es la forma correcta de hacerlo. Y, por cierto, debería usar los modelos de visualización como argumentos de acción, no como modelos de dominio o interfaces.

No solo el encuadernado de modelo personalizado parece complicado, ¿no perderé también mis DataAnnotaciones?

No sé por qué piensas que un encuadernador de modelo personalizado haría las cosas desordenadas. Para mí es una excelente manera de separar la lógica de mapeo en una clase reutilizable. Y, no, no perderá Anotaciones de datos. Funcionarán perfectamente bien en la instancia concreta que devolvería la carpeta de modelo personalizado.

+1

+1 Aquí hay una elaboración de algunos de los puntos: http://stackoverflow.com/questions/2899680/how-to-use-ninject-or-other-di-ioc-container-with-the-model-binder- in-asp-ne/2902871 # 2902871 –

+0

Gracias por eso, ¿conoce algún ejemplo práctico que exista al usar este tipo de solución? –

+0

@ PaulAldred-Bann http://msdn.microsoft.com/en-us/magazine/hh781022.aspx – fordareh

2

Cometí el mismo error. Ninject inyecta parámetros en su constructor, pero usted agregó parámetros a la acción del controlador de índice.

Se debe tener este aspecto: el sentido

public class HomeController : Controller 
{ 
    private IRecord _record; 

    public HomeController(IRecord record) 
    { 
     _record = record; 
    } 

    public ActionResult Index() 
    { 
     ViewBag.Message = "Modify this template to jump-start your ASP.NET MVC application. " + 
          _record .HelloWorld(); 

     return View(); 
    } 
} 

Hacer?

+2

Gracias, hice el mismo error :( –