Reasoning behind ASP.NET MVC ActionResult being an abstract class? [closed]
In ASP.NET MVC, the ActionResult
class, which is the base for all results returned by action methods from a controller, is defined as an abstract class with the single method (© Microsoft):
public abstract void ExecuteRes开发者_如何学运维ult(ControllerContext context);
Can you think of any specific reasons for this design? Specifically, it seems a bit weird to me, that
- there is no
IActionResult
interface, - and that the class would not be required at all, if there was such an interface.
After all, if this was an interface instead of that abstract class, there would be no need to extend a base class in order to create a new ActionResult
- one would just have to implement IActionResult
properly. In a world, err language, without multiple inheritance, this advantage would seem quite important to me.
Interfaces are great for allowing a class to implement multiple contracts, such as when you know that a type must be two different things. In some cases, this can encourage creating a type that has too many responsibilities.
Action results have a single responsibility and it didn't seem like there would be any scenario where you need an object to be both an action result and something else. Even if you did, it's possible to do via composition. So in this case, we went with ABS to allow us greater flexibility after we RTM to make changes if necessary.
However, if there's a specific scenario we're blocking in which an interface would be preferable, we'll consider it. We can always do it later in a manner that's not breaking.
You can even do it yourself by writing your own action invoker, which only requires you to implement IActionInvoker (an interface) and that invoker could check for your own IActionResult rather than ActionResult.
I'm gonna guess because they were anticipating the ActionResult to gain methods and properties over the life of the CTP/beta. If it was an interface, every change to IActionResult would break existing code. Adding another method to the abstract base class wouldn't cause any problems.
You implement interfaces and you inherit from abstract classes.
For me it is the difference between "being of a type" or "acting like a type"
Since C# doesn't support multiple inheritance you are forced to define your class as an ActionResult, instead of something that acts as an ActionResult.
Compare it to the class EventArgs. Why does it make sense to inherit EventArgs instead of a IEventArgs interface. Well because an EventHandler carries something around of type EventArgs, not something acting as an EventArgs class.
I know this isn't exactly what you are looking for but for hahas I opened up the MVC3 source, changed ActionResult to IActionResult, ran a couple of find and replaces and everything built fine.
This means to me that ActionResult is an abstract class for an API reason. Maybe its as simple as the MVC team wanted you to be able to use Fields or didn't want to give people the ability to do crazy IActionResult, ISomething, IMyNuttyThing.
A scenario that I would think IActionResult would help is for dependency injection. I would like to have one set of controllers that are shared between a SPA and a razor UI. In configuration I would like to dynamically set the application type and have my controllers
public ActionResult Get(){
var customer = new Customer();
return View(customer);
}
I would like the concrete View method to be determined at runtime based on the application type. ie. Json() or ViewResult()
The object I pass into the result for both cases is going to be the same.
Does that make sense? Or is this possible without an IActionResult?
精彩评论