CodeMash 2.0.1.0 REST Interfaces

This year's CodeMash website has two URI's that expose CodeMash Information:

The main news feed is already exposed via RSS (http://www.codemash.org/rss) but we may add a REST interface for that as well.

Session Information

Here's an example XML response for a single session (note that the <Abstract> content has been removed for brevity):

<Sessions xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <Session>
    <URI>/rest/sessions/The-case-for-Griffon-developing-desktop-applications-for-fun-and-profit</URI>
    <Title>The case for Griffon: developing desktop applications for fun and profit</Title>
    <Abstract>...</Abstract>
    <Start>0001-01-01T00:00:00</Start>
    <Difficulty>Beginner</Difficulty>
    <SpeakerName>Andres Almiray</SpeakerName>
    <SpeakerURI>/rest/speakers/Andres-Almiray</SpeakerURI>
  </Session>
</Sessions>

The <URI> node contains a URI that will return a single session.  The <Start> node is not set yet since the sessions have not been scheduled.  Once scheduling is complete, it will be available from this feed.

Speaker Information

Here's an example XML response for a single speaker (again, the <Biography> content has been removed for brevity):

<Speakers xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <Speaker>
    <Name>Chris Adamson</Name>
    <Biography>...</Biography>
    <Sessions>
      <SessionURI>/rest/sessions/Oh-Crap-I-Forgot-or-Never-Learned-C</SessionURI>
      <SessionURI>/rest/sessions/How-Do-You-Do-That-on-iPhone</SessionURI>
    </Sessions>
    <TwitterHandle />
    <BlogURL />
  </Speaker>
</Speakers>

Most speakers only have one session, but some have multiple.  You'll notice that the TwitterHandle and BlogURL for most of the speakers is empty.  That's because we forgot to ask for that information during the speaker submission process (oops!).  We're in the process of collecting the information and as we get it, we'll update our database and the information will be exposed to you.

Supported Formats

Right now, we support XML (default) and JSON formats.  If you don't add any extension to the REST URI's (or use ".xml") you'll get XML-formatted data (like above).  Use ".json" to return a JSON result.  We could support HTML – perhaps a simple <table> that dumps the information?  Let me know if you think that would be useful.

Technorati Tags: ,,

Is There An App For That?

Do you plan on using these API's to make some cool CodeMash apps?  Keep us updated on your progress by leaving a comment here, blogging about it or via Twitter using the hashtag #CodeMash.  We're looking forward to seeing what you build!

Posted by PSteele | with no comments
Filed under: ,

Using Windsor to inject dependencies into ASP.NET MVC ActionFilters

I'm using Windsor as my IoC container for an ASP.NET MVC application.  To get dependency injection in my controllers, I'm using a slightly modified WindsorControllerFactory from Andre Loker's post earlier this year.  It works great and allows me to easily test my controllers.

I've got some custom ActionFilters that would benefit from dependency injection.  Unfortunately, ActionFilters are attributes on controllers and methods and their instantiation is controlled by the framework.  There is no extension point to allow custom creation of the ActionFilters.  So I can't do constructor dependency injection.  However, I can do the next best thing – property dependency injection!

Custom Method Invoker

The ASP.NET MVC framework has an extensibility point when it comes to actually invoking actions on controllers.  The default ControllerActionInvoker does everything we need.  We need to modify it's behavior just a little bit to allow us to inject property dependencies.

There's a method on ControllerActionInvoker that is used whenever an action with filters is going to be executed.  It's appropriately named "InvokeActionMethodWithFilters".  This method is passed a collection of ActionFilters that have already been created by the framework (see, this is why we can't use constructor injection).  Thanks to Simone Chiaretta for blogging about his custom Ninject-based ActionInvoker, I was able to convert his to a Windsor-based invoker with relative ease:

public class WindsorActionInvoker : ControllerActionInvoker
{
    readonly IWindsorContainer container;
 
    public WindsorActionInvoker(IWindsorContainer container)
    {
        this.container = container;
    }
 
    protected override ActionExecutedContext InvokeActionMethodWithFilters(
            ControllerContext controllerContext,
            IList<IActionFilter> filters,
            ActionDescriptor actionDescriptor,
            IDictionary<string, object> parameters)
    {
        foreach (IActionFilter actionFilter in filters)
        {
            container.Kernel.InjectProperties(actionFilter);
        }
        return base.InvokeActionMethodWithFilters(controllerContext, filters, actionDescriptor, parameters);
    }
}

As you can see, it's pretty straightforward.  All we do is loop through all of the ActionFilters and inject any dependant properties.  Those of you familiar with Windsor will realize that the IKernel doesn't have an "InjectProperties" method.  I grabbed that from Jeremy Skinner's post about using AutoFac to inject properties into ActionFilters.  He created an extension method that uses reflection to resolve property dependencies:

public static class WindsorExtension
{
    public static void InjectProperties(this IKernel kernel, object target)
    {
        var type = target.GetType();
        foreach (var property in type.GetProperties(BindingFlags.Public | BindingFlags.Instance))
        {
            if (property.CanWrite && kernel.HasComponent(property.PropertyType))
            {
                var value = kernel.Resolve(property.PropertyType);
                try
                {
                    property.SetValue(target, value, null);
                }
                catch (Exception ex)
                {
                    var message = string.Format("Error setting property {0} on type {1}, See inner exception for more information.", property.Name, type.FullName);
                    throw new ComponentActivatorException(message, ex);
                }
            }
        }
    }
}

Now that we have the plumbing, let's hook it up!

Changes to WindsorControllerFactory

My current implementation of WindsorControllerFactor.GetControllerInstance looks like this:

protected override IController GetControllerInstance(Type controllerType)
{
    if( controllerType == null)
    {
        return base.GetControllerInstance(controllerType);
    }
    var controller = container.Resolve(controllerType) as Controller;
 
    return controller;
}

I just need to add a few lines of code to add my custom WindsorActionInvoker (which is registered inside Windsor!):

protected override IController GetControllerInstance(Type controllerType)
{
    if( controllerType == null)
    {
        return base.GetControllerInstance(controllerType);
    }
    var controller = container.Resolve(controllerType) as Controller;
 
    // new code
    if (controller != null)
    {
        controller.ActionInvoker = container.Resolve<IActionInvoker>();
    }
 
    return controller;
}

Using Property Injection with ActionFilters

So now lets look at how this can be used to add common data to every page.  The oft-used example of populating a list of sponsors just happened to be the exact scenario I was facing when I researched this solution.  With the WindsorActionInvoker in place, I can now create an ActionFilter to load my sponsor information into ViewData:

[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)]
public class LoadSponsorsAttribute : ActionFilterAttribute
{
    public ISponsorRepository SponsorRepository { get; set; }
 
    public override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        filterContext.Controller.ViewData["sponsors"] = SponsorRepository.GetSponsors();
        base.OnActionExecuting(filterContext);
    }
}

Now any method (or an entire controller class) can have this attribute applied and the sponsor information will be loaded before the action is called.  Here's an example:

[LoadSponsors]
public class ErrorController : ControllerBase
{
    public ActionResult Index()
    {
        return View();
    }
}

The list of sponsors is available in your view pages and user controls by simply looking at the ViewData dictionary:

var sponsors = (IEnumerable<Sponsor>) ViewData["sponsors"];

Final Polish

A nice solution, but the use of magic string constants ("sponsors") along with where the data are stored (ViewData) didn't sit well.  To fix that, I added a few extension methods to abstract out the access to the list of sponsors:

public static class Extensions
{
    private static class ViewDataKeys
    {
        public const string Sponsors = "sponsors";
    }
 
    public static void SetSponsors(this ControllerBase controller, IEnumerable<Sponsor> sponsors)
    {
        controller.ViewData[ViewDataKeys.Sponsors] = sponsors;
    }
 
    public static IEnumerable<Sponsor> GetSponsors(this ViewUserControl viewControl)
    {
        return viewControl.ViewData[ViewDataKeys.Sponsors] as IEnumerable<Sponsor>;
    }
}

The SetSponsors extension method allows me to change my LoadSponsorsAttribute to be simply:

public override void OnActionExecuting(ActionExecutingContext filterContext)
{
    filterContext.Controller.SetSponsors(SponsorRepository.GetSponsors());
    base.OnActionExecuting(filterContext);
}

The GetSponsors extension method on ViewUserControl allows the Sponsors.ascx that I used to display the list to simply call the GetSponsors() method – no access to ViewData or casting required:

var sponsors = this.GetSponsors();

Thanks to Andre Loker, Simone Chiaretta and Jeremy Skinner for making great posts that allowed me to piece all of this together!

Posted by PSteele | 3 comment(s)
Filed under: ,

Extension Properties

A couple of weeks ago, a post I made about Strongly Typed Session Variables in ASP.NET led to some interesting comments and discussion.  One of the comments asked "Why can't we just have extension properties…?".  Now, Eric Lippert has provided the answer.  See his "Why No Extension Properties?" post to read about the decisions that go into adding (or not adding) a language feature.

Technorati Tags: ,,
Posted by PSteele | 1 comment(s)
Filed under:

This isn't an error?

I just saw something odd in a diff before a check-in.  Basically, I had a trailing comma in an object initializer:

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            var foo = new Foo
                      {
                          A = "A",
                        B = "B",
                      };
        }
    }
 
    class Foo
    {
        public string A { get; set; }
        public string B { get; set; }
    }
}

I thought this would be an error until I did some searching and found that it is allowed according to "ECMA-334: 19.7 Array initializers":

[Note: Like Standard C++, C# allows a trailing comma at the end of an array-initializer. This syntax provides flexibility in adding or deleting members from such a list, and simplifies machine generation of such lists. end note]

Technorati Tags: ,,
Posted by PSteele | 7 comment(s)
Filed under:

Unit Tests and Debug.Assert()

I recently found some code that had a couple of issues:

  1. There was a try/catch block that did a "catch(Exception e)".  And no, it didn't rethrow the exception.  See item #2.
  2. Inside the exception handler, it had the following code:
catch (Exception e)
{
    Debug.WriteLine(e);
    Debug.Assert(false);
}

I thought long and hard on why anyone would do such a thing and I think I know why. Now, this is purely conjecture, but it does explain things.  This code was found inside a custom PropertyDescriptor – namely, the GetValue and SetValue methods both had this code.  I suspect that the Debug.Assert() was placed inside the catch block of these two methods so that no consumers of this component had to worry about possible data binding errors.  If there ever was a problem with data binding, the Debug.Assert(false) would throw up a dialog with a stack trace and some "Abort/Retry/Ignore" buttons, the user would click "Retry" and re-edit their data.  I don't like it, but since this component is used in a number of places in a data binding scenario, that's my theory.

The problem for me is that I needed to fix some bugs in this custom PropertyDescriptor and this code had no unit tests.  So before I could consider modifying anything, I had to get the current behavior under test.  Obviously, I had to remove the Debug.Assert(), but, for legacy code, I still had to have that (ugly!) behavior.

Since the Debug.Assert() is being used to report errors, I started by defining an interface that would be used for reporting errors:

public interface IPropertyDescriptorValueErrorReporting
{
    void SetValueError(Exception e);
    void GetValueError(Exception e);
}

I then moved the existing error handling code into a class I called "DefaultPropertyDescriptorValueErrorReporting":

public class DefaultPropertyDescriptorValueErrorReporting : IPropertyDescriptorValueErrorReporting
{
    #region IPropertyDescriptorValueErrorReporting Members
 
    public void SetValueError(Exception e)
    {
        Debug.WriteLine(e);
        Debug.Assert(false);
    }
 
    public void GetValueError(Exception e)
    {
        Debug.WriteLine(e);
        Debug.Assert(false);
    }
 
    #endregion
}

I then added an overload on the constructor of this custom property descriptor to accept an IPropertyDescriptorValueErrorReporting

public CustomPropertyDescriptor(string name, Type type, int index, IPropertyDescriptorValueErrorReporting errorReporting)
    : base(name, null)

For legacy code, the old constructor is modified to use the "DefaultPropertyDescriptorValueErrorReporting":

public CustomPropertyDescriptor(string name, Type type, int index)
    : this(name, type, index, new DefaultPropertyDescriptorValueErrorReporting())

Finally, we change the exception handler to call our interface methods:

catch (Exception e)
{
    errorReporting.GetValueError(e);
}

And we do a call to SetValueError in the SetValue exception handler.

Now I'm done!  I can proceed to create unit tests and I can pass in a mocked IPropertyDescriptorValueErrorReporting and set expectations that the GetValueError and SetValueError methods are called at the appropriate times.  Plus, I've also created an extension point so other applications can hook in to the error reporting and decide how to handle errors on a case-by-case basis.

Technorati Tags: ,,
Posted by PSteele | 4 comment(s)
Filed under: ,

LINQ and Homework

My daughter asked me to check her homework today.  One of the math problems was:

A book has 352 pages.  How many 4's were used to print all of the page numbers.

She got 35.  She explained how she arrived at that number and while her logic was good, it sounded too low to me.  I started thinking about it a little and then decided I could just write a few lines of C# code to figure out the answer.

As Visual Studio was starting up, I pictured the code in my head: initialize a counter to zero.  Loop through an int from 1 to 352 and see if the ToString() contains a 4.  If so, increase the counter.  Just as I was about to start typing, I thought, "Oh wait – I could do all of this with LINQ!".

var answer = Enumerable.Range(1, 352).Count(p => p.ToString().Contains("4"));

How did we ever manage before LINQ?  ;)

Technorati Tags: ,,
Posted by PSteele | 14 comment(s)
Filed under: ,

SRT's Bill Wagner wins "Emerging Leader of the Year" Award from Automation Alley

Last night, SRT vice president and co-founder Bill Wagner received the "Emerging Leader of the Year Award" from Automation Alley.  This annual event is Southeast Michigan’s most prestigious, competitive honors for technology organizations and their leaders.  As an employee of SRT solutions, this comes as no surprise to me.  Bill's continuous emphasis on new technologies is an everyday occurrence.  Whether he's speaking at User Groups (or running them!), updating Effective C# for .NET 4.0 or working on tough technology problems with clients, Bill is always the go-to guy with the answers.

And this is not simply me doing a "suck up" post for my boss.  It's a post about how lucky I am to work at SRT.  To be able to bounce ideas off of Bill Wagner any time I want is awesome!  It's about being a part of the company he and Dianne Marsh created.  The company that convinced Chris Marinos to come work with us instead some other large, Redmond-based software company and give him the opportunity to create Elevate – a .NET version of the popular Boost library for C++.  These things, along with all of the other great talent at SRT, make it a great place to work!

Thanks to Bill and Dianne for giving me the opportunity to work at SRT and congratulations to Bill on the award.  Well deserved!!

Technorati Tags: ,,
Posted by PSteele | with no comments
Filed under:

Strongly Typed Session Variables in ASP.NET MVC

This post was originally going to be a comment on Jarret@Work's blog post about "Using Extension Methods for Session Values", but I decided to make a full blog post out of it.  Jarret employed extension methods such Bar()/SetBar() and Foo()/SetFoo() to have strongly-typed session data.  While his method certainly works, I've taken a different approach that I think is a bit more flexible and reads better.

Like Jarret, I maintain a "SessionKeys" class – there is no easier way to ask for trouble than using a magic string buried across 4 or 5 web pages.  But I expose my session data in a base class that all controllers in my application derive from.  Here's a sample from my post on unit testing ASP.NET MVC controllers:

public abstract class BaseController : Controller
{
    protected SpeakerInfo SpeakerInfo
    {
        get
        {
            var info = Session[SessionKeys.SpeakerInfoKey] as SpeakerInfo;
            if( info == null)
            {
                info = new SpeakerInfo();
            }
 
            return info;
        }
        set
        {
            Session[SessionKeys.SpeakerInfoKey] = value;
        }
    }
}

Now all of my controllers inherit from BaseController and they can easily access the data stored in the Session by utilizing the SpeakerInfo property.  I like this over Jarret's implementation for two reasons:

  1. Properties make the code more readable than get/set methods (in my opinion).
  2. I can change where/how SpeakerInfo is stored without affecting the rest of my code (perhaps to use a database instead of Session).

To be fair, #2 is also possible with Jarret's implementation.  He can change the code in his get/set methods.  But his code would still read "Session.Bar()" and "Session.SetBar()" when (if the implementation was changed to use a database), it wouldn't really be using the Session.

Technorati Tags:
Posted by PSteele | 18 comment(s)
Filed under: ,

Handy Extension Methods for ASP.NET MVC's UrlHelper

Mickael Chambaud posted three extension methods he created for UrlHelper: Image(), Stylesheet() and Script().  They make it pretty easy to keep your images, stylesheets and scripts organized in a single location – without the need for you to remember where they are placed.  And if you need to move things around for some reason, you only have to change the extension methods.

Posted by PSteele | 1 comment(s)
Filed under: ,

Enabling Windsor Integration in MonoRail

I recently wanted to take on old MonoRail application and update it to use Windsor for dependency injection (DI).  The application stated as a sort of prototype and slowing grew into a decent sized application.  There's a couple of places that I want to add some unit tests and I could really benefit from DI.  So I sat down to hook Windsor into the application.

There's already documentation on how to integrate Windsor into MonoRail.  After all, they kind of "grew up" together.  However, the documentation is a little old and MonoRail has gone through a number of changes (some breaking) and improvements.  The "using MonoRail" site (a sort of wiki-like site) had some information on integrating Windsor into MonoRail which was more up-to-date than the Castle docs, but still left out an important section about ViewComponents.  So I thought I'd bring everything I learned into a single blog post.  I plan to take much of this and use it to update the Castle docs as well as the "using" site.

Requirements

You'll need to reference a few extra assemblies in your MonoRail application:

  • Castle.DynamicProxy2.dll
  • Castle.MicroKernel.dll
  • Castle.Windor.dll
  • Castle.MonoRail.WindsorExtension.dll

Custom Container

The first thing is to create a sub-class of the Windsor container for your MonoRail application.  This specialized version of the container will add the following capabilities:

  1. It will add a new facility which will automatically configure our Controllers for a transient lifestyle (one instance per request).  Windsor's default lifestyle is Singleton (imagine having only a single instance for each controller – yikes!!).
  2. It will automatically register all of our controllers for us.  This is optional as you can individually register each controller, but I find the automatic registration much easier.
  3. It will automatically register all of our ViewComponents.  Like controllers, this could be done individually, but this is easier.

Our custom container is really quite simple.  We'll create WebAppContainer.cs in our App_Code directory.  Our constructor will call the base class constructor that will initialize the container from the config file (web.config):

using Castle.Core.Resource;
using Castle.Windsor.Configuration.Interpreters;
using Castle.MonoRail.WindsorExtension;
using Castle.Windsor;
using Castle.MicroKernel.Registration;
using Castle.MonoRail.Framework;
using Castle.Core;
 
public class WebAppContainer : WindsorContainer
{
    public WebAppContainer()
        : base(new XmlInterpreter(new ConfigResource()))
    {
    }
 
    public void Init()
    {
    }
}

Now let's work on our 3 items above.  We'll plug all of this into our Init() method which we'll call later when we initialize our container.

First, we add a facility for MonoRail integration.  This facility is part of MonoRail:

AddFacility("rails", new MonoRailFacility());

Next, we register all of our controllers (yes, in one statement).  My controllers are in a separate assembly so this is how my registration looks:

Register(
    AllTypes.Of<IController>()
    .FromAssemblyNamed("YourAssemblyName.Controllers"));

If your controllers are directly in your web application, you can change "FromAssemblyNamed(…)" to "FromAssembly(Assembly.GetExecutingAssembly())".

Now we also need to register our ViewComponents.  This registration will also make sure that the ViewComponents are set up with a transient lifestyle:

Register(
    AllTypes.Of<ViewComponent>()
        .FromAssemblyNamed("YourAssemblyName.Controllers")
        .Configure(cr => cr.Named(cr.ServiceType.Name).LifeStyle.Is(LifestyleType.Transient))
    );

That's it for the container!  Our complete, customized container looks like this:

using Castle.Core.Resource;
using Castle.Windsor.Configuration.Interpreters;
using Castle.MonoRail.WindsorExtension;
using Castle.Windsor;
using Castle.MicroKernel.Registration;
using Castle.MonoRail.Framework;
using Castle.Core;
 
public class WebAppContainer : WindsorContainer
{
    public WebAppContainer()
        : base(new XmlInterpreter(new ConfigResource()))
    {
    }
 
    public void Init()
    {
        AddFacility("rails", new MonoRailFacility());
 
        Register(
            AllTypes.Of<IController>()
            .FromAssemblyNamed("YourAssemblyName.Controllers"));
 
        Register(
            AllTypes.Of<ViewComponent>()
                .FromAssemblyNamed("YourAssemblyName.Controllers")
                .Configure(cr => cr.Named(cr.ServiceType.Name).LifeStyle.Is(LifestyleType.Transient))
            );
    }
}

Integrating Our Container

Now we need to hook this container into our web application.  We need to plug this into our custom HttpApplication (usually, your GlobalApplication.cs).  First, we need to add the IContainerAccessor interface:

public class GlobalApplication : HttpApplication, IContainerAccessor

Now add a static class variable to old our container:

private static WebAppContainer container;

Now we need to create the container when our application first starts and dispose of it when the application ends.  This is easy by hooking into the Application_OnStart and Application_OnEnd events.  The OnStart event is where we call the container's Init() method.

public void Application_OnStart()
{
    container = new WebAppContainer();
    container.Init();
}
 
public void Application_OnEnd()
{
    container.Dispose();
}

Finally, we need to implement the IContainerAccessor.Container property to return our custom container:

public IWindsorContainer Container
{
    get { return container; }
}

We're almost there!

Web.config Changes

Now that we're using Windsor, we need to configure our web.config.  Add the following section handler declaration in the <configSections> node:

<configSections>
    ..
    <section name="castle"
             type="Castle.Windsor.Configuration.AppDomain.CastleSectionHandler, Castle.Windsor" />
    ..
</configSections>

And add a "useWindsorIntegration" attribute to your existing <monorail> node, setting its value to "true":

<monorail useWindsorIntegration="true">

Since you probably don't have any components to register (since you haven't been using Windsor until now), you can add an empty <castle> section.  When you're ready to configure your components to enable DI and loose coupling, see the Windsor Configuration Reference at the Castle Project site.

That's It!

You're done.  We added a new, 33-line WebAppContainer.cs, added about 6-8 lines to GlobalApplication.cs and added a few lines to web.config.  Now we've got the full power of Castle's dependency injection to allow us to build loosely-couple, easily testable controllers and view components.

Technorati Tags: ,,,
Posted by PSteele | 1 comment(s)
Filed under: , ,
More Posts Next page »