Pregunta

Vamos a decir que tengo una interfaz como:

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

Y en ASP.NET MVC Tengo una forma que los puestos a una acción de controlador de esta manera:

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

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

Donde SimpleThing es una clase concreta de que apenas implementos iThing .

Sin embargo, me gustaría que todos mis métodos para hacer frente a la interfaz. Tengo un conjunto de datos que utiliza NHiberate y su propia iThing aplicación (vamos a llamarlo RealThing ). No puedo pasar el SimpleThing a ella, ya que se quejan de una "entidad desconocida".

¿Alguien tiene alguna idea acerca de una forma más limpia de hacer esto? Estaba pensando en algo en la línea de la utilización de una clase de fábrica. Pero ¿cómo iba a obtener el formulario ligante MVC para usarlo?

Gracias!

¿Fue útil?

Solución 3

Hubo algunas buenas sugerencias aquí y que en realidad se le ocurrió una solución que funcione. Sin embargo, acabé con algo en conjunto. Acabo de crear modelos específicos para los datos del formulario que estaba publicando y se utiliza el ligante modelo por defecto.

Mucho más simple y que me permite la captura de datos que no es parte de mi modelo de dominio (es decir., Como un campo "comentarios").

Otros consejos

Puede utilizar encargo enlazadores de modelos . Sin embargo el artículo en MSDN es totalmente inútil. Así que es mejor emplear búsqueda y encontrar algo mejor. Hay planaty de artículos disponibles.

Se me ocurrió dos métodos para esto.

La primera fue la de añadir código para mi clase de NHibernate Repositorio de traducir el tipo simple POCO utilizado por el controlador MVC ( SimpleThing ) para el tipo de entidad que NHibernate quería ( 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;
        }            
    }

Por lo tanto, cualquier método en el repositorio puede llamar GetKnownEntity (T artículo) y se copiará las propiedades del elemento que se pasa en el tipo que quiere NHibernate. Obviamente, esto se sentía un poco torpe, por lo que se veía en los aglutinantes modelo personalizado.


En el segundo enfoque, he creado un modelo personalizado aglutinante de la siguiente manera:

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

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

        return new T();                       
    }

}

Entonces registrada que en Global.asax.cs con:

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

Y funciona muy bien con una acción de controlador que tiene este aspecto:

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

Me gusta el segundo enfoque, pero la mayoría de mis cosas inyección de dependencia es de la clase controlador. No me gusta tener que añadir todas estas asignaciones ModelBinder en Global.asax.cs.

Esto no es dirrect unswer a su pregunta.

Utilizamos enfoque ligeramente diferente para lidiar con el mismo problema que tiene. Nuestros controladores acepta dtos que responden campo de entidad persistente por el campo. Luego de usuario AutoMapper a crear entidades persisten que irán a la base de datos. Esto elimina las interfaces unnessesery y ajustada API del lado público (significa que el cambio de nombre de campo persistencia del objeto no se romperá nuestro código de cliente).

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top