Domanda

Diciamo che ho un'interfaccia simile:

interface IThing {
   int Id { get; set; }
   string Title { get; set; }
}

E in ASP.NET MVC Ho una forma che i posti ad un'azione di controllo in questo modo:

 [AcceptVerbs(HttpVerbs.Post)]
 public ActionResult NewThing([Bind(Exclude = "Id")] SimpleThing thing) {

    // code to validate and persist the thing can go here            
 }

Dove SimpleThing è una classe concreta che appena implementa IThing .

Tuttavia, vorrei tutti i miei metodi per trattare con l'interfaccia. Ho un gruppo di dati che utilizza NHiberate e il proprio IThing implementazione (chiamiamolo RealThing ). Non posso passare il SimpleThing ad esso, perché si lamenta una "entità sconosciuta".

Qualcuno ha qualche idea su un modo più pulito per fare questo? Stavo pensando a qualcosa lungo le linee di utilizzo di una classe di fabbrica. Ma come faccio a ottenere la forma legante MVC per usarlo?

Grazie!

È stato utile?

Soluzione 3

Ci sono stati alcuni buoni suggerimenti qui e io in realtà si avvicinò con una soluzione che funziona. Tuttavia, ho finito con qualcosa di completamente. Ho appena creato modelli specifici per i dati del modulo ero distacco e usato il legante modello predefinito.

Molto più semplice e mi permette di catturare dati che non fa parte del mio modello di dominio (es. Come un campo "commenti").

Altri suggerimenti

È possibile utilizzare personalizzato modello leganti . Tuttavia articolo su MSDN è del tutto inutile. Quindi meglio impiegare ricerca e trovare qualcosa di meglio. Ci sono planaty di articoli disponibili.

Sono venuto con due approcci a questo.

Il primo è stato quello di aggiungere il codice per la mia classe di NHibernate Repository di tradurre il tipo semplice POCO utilizzato dal controller MVC ( SimpleThing ) per il tipo di entità che NHibernate ha voluto ( RealThing ):

/// <summary>
/// A NHibernate generic repository.  Provides base of common 
/// methods to retrieve and update data.
/// </summary>
/// <typeparam name="T">The base type to expose 
/// repository methods for.</typeparam>
/// <typeparam name="K">The concrete type used by NHibernate</typeparam>
public class NHRepositoryBase<T, K> 
    : IRepository<T>
    where T : class
    where K : T, new()
{
    // repository methods ...

    /// <summary>
    /// Return T item as a type of K, converting it if necessary
    /// </summary>        
    protected static K GetKnownEntity(T item) {
        if (typeof(T) != typeof(K)) {
            K knownEntity = new K();

            foreach (var prop in typeof(T).GetProperties()) { 
                object value = prop.GetValue(item, null);
                prop.SetValue(knownEntity, value, null);
            }

            return knownEntity;
        } else {

            return (K)item;
        }            
    }

Quindi, qualsiasi metodo nel repository può chiamare GetKnownEntity (T articolo) e copierà le proprietà del prodotto si passa al tipo che NHibernate vuole. Ovviamente questo si sentiva un po 'goffo, così ho guardato a leganti modello personalizzato.


Nel secondo approccio, ho creato un modello personalizzato legante in questo modo:

public class FactoryModelBinder<T> 
    : DefaultModelBinder 
    where T : new() 
{

    protected override object CreateModel(ControllerContext controllerContext, 
                                          ModelBindingContext bindingContext, 
                                          Type modelType) {

        return new T();                       
    }

}

Poi ho registrato che in Global.asax.cs con:

ModelBinders.Binders.Add(typeof(IThing), 
            new FactoryModelBinder<RealThing>());

E funziona bene con un'azione di controllo che assomiglia a questo:

[AcceptVerbs(HttpVerbs.Post)]
public ActionResult NewThing([Bind(Exclude = "Id")] IThing thing) {
    // code to process the thing goes here
}

Mi piace il secondo approccio, ma la maggior parte delle mie cose iniezione di dipendenza è nella classe Controller. Non mi piace dover aggiungere tutti questi mapping ModelBinder in Global.asax.cs.

Questa non è dirrect unswer alla tua domanda.

Usiamo approccio leggermente diverso per affrontare lo stesso problema che avete. I nostri controllori accetta DTOs che corrispondono campo entità persistente da parte di campo. Poi abbiamo utente automapper di creare entità persisten che andranno al database. Questo elimina le interfacce unnessesery e blinda API pubblico di fronte (significa che la ridenominazione persistenza campo dell'oggetto non si romperà il nostro codice cliente).

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top