2008-11-29 22 views
5

En ASP.NET MVC, la clase ActionResult, que es la base de todos los resultados devueltos por los métodos de acción de un controlador, se define como una clase abstracta con el método individual (© Microsoft):Razonamiento detrás de ASP.NET MVC ActionResult es una clase abstracta?

public abstract void ExecuteResult(ControllerContext context); 

¿Puede usted pensar en ¿Alguna razón específica para este diseño? En concreto, se parece un poco raro para mí, que

  • no hay IActionResult interfaz,
  • y que no se requeriría la clase en absoluto, si había una interfaz de este tipo.

Después de todo, si se trataba de una interfaz en lugar de esa clase abstracta, no habría necesidad de extender una clase base con el fin de crear una nueva ActionResult - uno sólo tiene que poner en práctica IActionResult correctamente. En un mundo, un lenguaje erróneo, sin herencia múltiple, esta ventaja me parecería muy importante.

+0

Envié un correo electrónico a Phil Haack (PM en ASP.NET MVC en Microsoft) con un enlace a esta pregunta, espero que encuentre algo de tiempo para explicar en los próximos días. –

+0

Buena idea, gracias. – hangy

+0

¿Hay algún escenario específico en el que esté bloqueado en este caso particular? – Haacked

Respuesta

12

Las interfaces son geniales para permitir que una clase implemente contratos múltiples, como cuando sabe que un tipo debe ser dos cosas diferentes. En algunos casos, esto puede alentar la creación de un tipo que tenga demasiadas responsabilidades.

Los resultados de la acción tienen una responsabilidad única y no parece que haya ningún escenario donde necesite que un objeto sea tanto un resultado de acción como algo más. Incluso si lo hizo, es posible hacerlo a través de la composición. Entonces, en este caso, optamos por ABS para permitirnos una mayor flexibilidad luego de que RTM haga los cambios necesarios.

Sin embargo, si hay un escenario específico que estamos bloqueando en el que una interfaz sería preferible, lo consideraremos. Siempre podemos hacerlo más tarde de una manera que no se rompa.

Incluso puede hacerlo usted mismo escribiendo su propio invocador de acciones, que solo requiere que implemente IActionInvoker (una interfaz) y que invocador pueda verificar su propio resultado de IAction en lugar de ActionResult.

+0

Me encontré con un problema hoy que me bloquea. Quiero implementar un ActionResult como un ExpandoObject para que el controlador pueda agregar miembros al ActionResult de forma dinámica. Pero mi clase no puede ser una ActionResult _and_un ExpandoObject sin MI ... – joshperry

+0

Lo que puede hacer es tener una clase ActionResult que también implemente IDynamicMetaObjectProvider (vea http://msdn.microsoft.com/en-us/library/system .dynamic.idynamicmetaobjectprovider.aspx). En la implementación de esa interfaz, usted delega a un objeto Expando interno. – Haacked

+1

Me encanta cuando Phil Haack viene del equipo ASP.NET MVC y da la respuesta definitiva. Felicitaciones a su participación en la comunidad. –

2

Voy a adivinar porque anticipaban que el ActionResult obtendría métodos y propiedades durante la vida del CTP/beta. Si fuera una interfaz, cada cambio en IActionResult rompería el código existente. Agregar otro método a la clase base abstracta no causaría ningún problema.

+0

¡atrás de la red! – Tablet

+0

Los cambios de ruptura se realizaron durante la fase CTP de todos modos, por lo que probablemente sería una razón débil. :) De todos modos, supongo que podría estar cerca de lo que pensaban. Aunque espero que decidan sobre alguna interfaz en lugar de la clase abstracta antes de un lanzamiento. – hangy

1

Implementa interfaces y hereda de clases abstractas.
Para mi es la diferencia entre "ser de un tipo" o "actuar como un tipo de"

Puesto que C# no soporta herencia múltiple se ve obligado a definir la clase como un ActionResult, en lugar de algo que actúa como un ActionResult.

Compáralo con la clase EventArgs. ¿Por qué tiene sentido heredar EventArgs en lugar de una interfaz IEventArgs? Bueno, porque un EventHandler lleva algo de tipo EventArgs, no algo que actúe como una clase EventArgs.

1

Sé que esto no es exactamente lo que estás buscando, pero para hahas abrí la fuente MVC3, cambié ActionResult a IActionResult, ejecuté un par de find y reemplazos y todo funcionó bien.

Esto significa para mí que ActionResult es una clase abstracta por un motivo API. Tal vez es tan simple como que el equipo de MVC quería que pudieras usar Fields o no quisiste darle a la gente la habilidad de hacer crazy IActionResult, ISomething, IMyNuttyThing.

1

Un escenario que creo que IActionResult ayudaría es para la inyección de dependencia. Me gustaría tener un conjunto de controladores compartidos entre un SPA y una IU de afeitar. En la configuración me gustaría establecer dinámicamente el tipo de aplicación y tienen mis controladores

public ActionResult Get(){ 
    var customer = new Customer(); 
    return View(customer); 
} 

Me gustaría que el método de vista concreto que se determine en tiempo de ejecución en función del tipo de aplicación. es decir. Json() o ViewResult()

El objeto que paso al resultado en ambos casos va a ser el mismo.

¿Tiene sentido? ¿O es esto posible sin un IActionResult?

+1

Bienvenido a Stack Overflow. Publicaste tu pregunta en una sección reservada para respuestas. Lea en [Preguntas frecuentes] (http://stackoverflow.com/faq) - contiene mucha información útil, incluida una guía sobre [Cómo preguntar] (http://stackoverflow.com/faq#howtoask). – Perception

Cuestiones relacionadas