Author Archive for JC

03
Jul

ASP.NET MVC - ControllerActionInvoker: Part 1

Whenever I give a session on ASP.NET MVC I always make a point to highlight the extensibility pipeline and how easily you can replace the default behavior/conventions with just about anything you can imagine (you should be happy with your code right?). I tend to focus on controller factories, action results, action filters, and view engines as the primary candidates for extension, because those enable a whole slew of fairly common scenarios for developers. But I’d hate to feel like I’m playing favorites…

While I was in Sydney last month, one of the attendees at an ASP.NET MVC session I was giving asked me when and why you would ever create your own custom ControllerActionInvoker, which I thought was a great question, and one that I foolishly haven’t been discussing. I’d hate to feel like I’m skirting over any interesting details, so I’m going to put together a couple of blog posts to showcase creating a custom ControllerActionInvoker.

The first thing to tackle when thinking about reasons to extend the ControllerActionInvoker class is to understand what exactly its role is in the overall request execution process. This diagram shows a decent (emphasis on decent) illustration of where the invoker sits in the lifecycle:

img-07-03-2008.png

Notice that the invoker comes into the picture based on its association with the Controller. By this, I specifically mean the Controller class, so if you create your own IController implementation, the ControllerActionInvoker isn’t in the picture anymore (unless you leverage it from your implementation as well). When a controller’s Execute method is called (by the routing engine), the controller grabs its invoker and passes the request on to it. So it isn’t actually the Controller class that executes its own actions, it is its invoker that does. This may sound a little strange, but it makes sense as you dig deeper…

Once the invoker has received “focus” from the controller, it essentially has five tasks that it attempts to perform, all of which represent a possible point of extension, and can be used to enable some pretty interesting stuff:

  1. Retrieve a MethodInfo that represents the requested action method
  2. Determine where to retrieve values for the action method’s parameters (if any exist)
  3. Get a list of all action filters associated with the action method
  4. Execute the action method (along with any filters)
  5. Execute the action result (along with any filters)

So how does this process play out in the default invoker implementation? If the controller’s ActionInvoker property isn’t specifically set, it news up an instance of the ControllerActionInvoker class, and hands it the reigns. It’s behavior aligns to the above five steps as follows:

  1. The invoker reflects against its parent controller, looking for a public method with the exact name of the requested action. The method can’t be static, have generic parameters, or be salted with the NonAction attribute.
  2. The invoker looks to see if the method has any parameters (can’t be out/ref) and if so, looks for values with the same name as the parameter in the following locations (in this order):
    1. Route value
    2. Query String
    3. Form
    4. Cookie
    5. Server variable
  3. The invoker looks for filters that are represented as attributes that were appended to the action method (and inherit from ActionFilterAttribute), as well as its parent controller
  4. This is a three step process:
    1. Call the OnActionExecuting method of all action filters associated with the action
    2. Execute the actual action method (capturing the returned ActionResult for later use)
    3. Call the OnActionExecuted method of all action filters associated with the action
  5. This is a three step process:
    1. Call the OnResultExecuting method of all action filters associated with the action
    2. Call the ActionResult’s ExecuteResult method
    3. Call the OnResultExecuted method of all action filters associated with the action

If we determine that we want to replace one of those steps with our own behavior, how can we go about doing that? All we have to do is subclass ControllerActionInvoker, and assign an instance of our invoker to the controller’s ActionInvoker property, so that it uses our implementation instead of the default. When deciding how we’d like to inject our custom invoker, we have two choices:

  1. Create a custom controller factory
  2. Create a custom controller

If you decide to create a custom controller factory, the easiest path to take would be to create a class that inherits from DefaultControllerFactory (provides a lot of useful functionality on top of IControllerFactory), and override its GetControllerInstance method, where you would create an instance of your invoker, and inject it into the created controller, like so:

public class CustomFactory : DefaultControllerFactory
{
    protected override IController GetControllerInstance(Type controllerType)
    {
        var controller = (Controller)base.GetControllerInstance(controllerType);
        controller.ActionInvoker = new CustomInvoker(new ControllerContext(base.RequestContext, controller));
        return controller;
    }
}

Then you would inject your custom controller factory into the pipeline by letting the ControllerBuilder know you want to use it, like so:

ControllerBuilder.Current.SetControllerFactory(typeof(CustomFactory));

This approach works great if you want all controllers in your web application to automatically receive the custom invoker. But, maybe you want your controllers to have to “opt-in” to leveraging the custom invoker, which is when creating a custom controller might work better, because then your controllers would have to specifically inherit from the custom controller class in order to receive the custom invoker.

Because the invoker relies on ControllerContext, which isn’t provided to the Controller class until its Execute method is called, if you choose to subclass the Controller class, you can simply override its Execute method. This allows you to new up an instance of our custom invoker, leveraging the provided ControllerContext, like so:

public class CustomController : Controller
{
    protected override void Execute(ControllerContext controllerContext)
    {
        ActionInvoker = new CustomInvoker(controllerContext);
        base.Execute(controllerContext);
    }
}

Now when I create a new controller, instead of inheriting from the Controller class, I can just inherit from CustomController, and benefit from my custom invoker:

public class HomeController : CustomController
{
	// Action methods...
}

Now that we’ve discussed what responsibilities the ControllerActionInvoker actually has, and where it rests in the pipeline, in the next few blog posts we’ll see what kind of scenarios we can enable by replacing some of the default behavior with our own.

24
Jun

Entity Framework v2 - Transparent Design Process

If you’ve followed the Astoria team blog for the last year (well almost a year), you’ve no doubt noticed the team’s transparency in discussing design decisions. In addition, they were very open to feedback, and in many cases, it was actually customer comments/suggestions that solidified the direction of certain features.

Today, the Entity Framework team has followed suit and started a new blog that will focus on providing the community with a view into their design process for v2. The initial post outlines a list of features being evaluated for inclusion and shows a glimpse into what can be expected with the release. I encourage everyone to take advantage of this resource and voice your opinions on forthcoming design discussions.

18
May

Entity Framework comparisons

Daniel Simmons just posted a great article comparing the Entity Framework to some other available options to .NET developers (ADO.NET, LINQ To SQL, NHibernate). While the entire write-up is really good, I think his concluding sentence sums it up really nicely: “The EF is not just an ORM–it’s the first step in a much larger vision of an entity-aware data platform.”

That’s the point I always try to make clear when speaking with people about the Entity Framework. The EF vs. NHibernate argument doesn’t really make sense because they aren’t 1:1 technologies, and have significantly different goals in the long-term. Is NHibernate a more mature ORM today? Yes, of course it is, because it’s been around a lot longer. Does EF provide a very strong ORM as well as a rich modeling tool that can be leveraged in numerous scenarios and continue to return on it’s investments? Yes, I’d like to think so.

If I decide to adopt the EDM as my application modeling/mapping tool, not only can I begin consuming it in my applications using the EF, but I can then expose it over the web using ADO.NET Data Services, and I can also build on top of it to create an ASP.NET Dynamic Data application (or enhance an existing WebForm application with Dynamic Data behavior). As of the release of .NET 3.5 SP1, you already have three compelling scenarios that leverage your single EDM. Moving forward you can imagine that list of EDM consumers will grow significantly.

Keep in mind that both ADO.NET Data Services and ASP.NET Dynamic Data are not coupled to the Entity Framework, but they provide first-class support for it out of the box, which makes the integration between them very strong. For instance, if using an EDM as the data source for an ADO.NET Data Service, the model has clear definitions as to what each entity type’s key is (where it’s a composite or singluar key) built-in, so you don’t have to do anything extra to instruct the data service. If you’re using any other data source, your entity type’s key properties have to abide by a specific criteria, which could include you having to salt them with a specific attribute.

17
May

ILab #6 - Mooncake

When I need to get into “the zone” while coding, nothing does the trick better than some uptempo instrumental rock music. It’s inherit ability to motivate is undeniable, and I find it goes a long way towards enhancing creativity as well.

My current drug of choice is a Russian band named Mooncake (how can you not just love that?). I’ve been rocking their latest album this week and I must say it provides the perfect mid-day boost. They play great rock music, but not in the bland/gritty sense. They’re epic but not over the top. They’re catchy but not cheesy. They’re…well, you get the point.

My favorite track by them is “Short Stories of Methuselah Tree” (it pretty much dominates), but the rest of the album holds it own just fine. They’re definitely worth checking out.

Listen
Website

16
May

XPI Anyone?

In .NET 3.5 the System.Xml.Linq assembly was introduced, adding a new set of classes for constructing XML, as well as extensions for querying XML using LINQ. The term LINQ To XML was coined and has since referred to both aforementioned tasks. While the name LINQ To XML makes perfect sense for the act of writing a LINQ statement against an XML source, the name has little application for the act of building an XML tree using the new API. For the sake of explicitness, I’d like to see a name that could be given to the group of “X Classes” within the System.Xml.Linq namespace (aka the XSpace) that could eliminate any ambiguity when differentiating between it and the actual use of LINQ To XML.

I was pondering over the name XPI (XML programming interface). It seems to make sense on a few different levels:

  1. It is indeed a programming interface for XML…
  2. Every class within the API is prefixed with “X”, hence it isn’t an API but rather an XPI…
  3. It’s an acronym and we all know that we need more of those…

This probably isn’t the best name in the world, but it certainly has a nice ring to it…

  • “So I was out the other night, minding my own business, and all of a sudden this dude gets up in my grill questioning my XPI skills and I was like what?!?!”
  • “I knew I liked the girl after she admitted her fixation with 80’s hair metal, but it wasn’t until she told me she was into XPI that I realized I loved her!!!”
  • “I’ll take .NET 3.5 XML programming interfaces for 300 hundred Alex” - Contestant
    “This XML programming interface was introduced in .NET 3.5 and is pretty freakin sweet.” - Alex
    “What is XPI Alex?” - Apparently cool contestant

Need I say more? If you don’t believe me, don’t take my word for it…

beercat.jpg