5

Attualmente sto lavorando su un progetto MVC 3 utilizzando Ninject come mio DI, gli oggetti business sono memorizzati in un assembly separato. Mi sto imbattendo in un problema con i parametri del controller, quando postback per le operazioni CRUD sto ricevendo l'errore "Impossibile creare un'istanza di un'interfaccia". Sono consapevole del fatto che non è possibile creare un'istanza di un'interfaccia, ma sembra che l'unico modo per aggirare questo problema è quello di utilizzare un modello di raccoglitore personalizzato e passare a FormCollection. Questo mi sembra davvero disordinato e voglio mantenere il codice del tipo più specifico possibile rispetto al progetto - quindi interfacce ovunque e Ninject per DI i calcoli. Non solo il binding personalizzato del modello sembra disordinato - non perderò anche le mie annotazioni DataAnnuncio?MVC 3 entità passante come interfaccia

Alcuni codice per descrivere quello che ho:

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

Qualcuno ha eseguito in prima? Come l'hai superato?

Grazie!

risposta

3

I dati trasmessi all'azione del controller sono semplicemente supporti per i valori. Non ci dovrebbe essere alcuna logica in loro quindi non c'è nulla da cui disaccoppiare. È possibile utilizzare tipi concreti (ad esempio record) al posto di interfaccia (iRecord)

+1

Non dovrei quindi infrangere la regola dell'accoppiamento lento? Cosa succede se voglio/devo cambiare il nome del mio metodo concreto per qualche motivo, cioè Record diventa RecordDifferent. Posso avere RecordDifferent che implementa IRecord e cambiare il mio DI per iniettare RecordDifferent in tutti i casi di IRecord. –

+1

Preferisco utilizzare le classi per contenitori modello e ereditarietà piuttosto che interfacce. Di default, DI non viene utilizzato per creare oggetti passati alle azioni. Uso DI solo per la logica reale non per i contenitori di dati – Novakov

+0

Non ho veramente capito cosa intendevi inizialmente, ma avendo progredito un po 'con questo progetto ho realizzato che sto cercando di "disaccoppiare" i contenitori di dati semplici come hai detto tu. Non c'è alcun comportamento (ancora) in nessuno degli oggetti POCO che mappano una tabella di database e quindi non c'è alcun motivo per interfacciarli a questi - né usare una fabbrica per istanziarli. Immagino che quello che ho avuto problemi di comprensione è che il disaccoppiamento dovrebbe essere veramente usato per oggetti con comportamento piuttosto che solo proprietà dei dati. –

6

ma sembra che l'unico modo per ottenere intorno a questo è quello di utilizzare un modello personalizzato legante

un modello personalizzato legante è il modo corretto di andare. E dal modo in cui dovresti usare i modelli di visualizzazione come argomenti di azione, non i modelli di dominio o le interfacce.

Non solo il binding personalizzato del modello sembra disordinato - non perderò anche le mie annotazioni DataAnnuncio?

Non so perché pensi che un raccoglitore di modelli personalizzato possa rendere le cose disordinate. Per me è un ottimo modo per separare la logica di mappatura in una classe riutilizzabile. E no, non perderete DataAnnotations. Funzioneranno perfettamente bene sull'istanza concreta che il legatore modello personalizzato sarebbe tornato.

+1

+1 Ecco un'elaborazione di alcuni dei punti: http://stackoverflow.com/questions/2899680/how-to-use-ninject-or-other-di-ioc-container-with-the-model-binder- in-asp-ne/2902871 # 2902871 –

+0

Grazie per quello, conosci qualche esempio pratico che esiste con questo tipo di soluzione? –

+0

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

2

Ho fatto lo stesso semplice errore. Ninject inietta i parametri nel costruttore, ma hai aggiunto parametri all'azione del controller indice.

Esso dovrebbe essere simile a questo:

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

senso?

+2

Grazie, ho fatto lo stesso errore :( –

Problemi correlati