Maarten Balliauw {blog}

ASP.NET, ASP.NET MVC, Windows Azure, PHP, ...

NAVIGATION - SEARCH

Book review: Refactoring with Visual Studio 2010

refactoring-with-microsoft-visual-studio-2010Yet again, Packt Publishing has sent me a book for review. For once, one without the typical orange/black cover but instead a classy white/black cover: Refactoring with Visual Studio 2010 by Peter Ritchie.

Since my book shelf is quite heavy on the Packt side (really, almost have their complete collection I guess, they keep sending me books), I was a bit in doubt if I should write yet another review for one of their books as I think I’m starting to sound like a Packt marketing guy. After reading it though, I thought that this book deserves some credit!

I’m going to skip the official wording on what the book is all about: the title suggest refactoring with Visual Studio 2010, but that title covers only 5% of the book’s contents. This is also reflected in the book: it describes a refactoring, in 8 out of 10 cases followed by a sentence “that this refactoring is not supported in Visual Studio 2010”. However, all refactorings are clearly explained with practical, easy to grasp sample code.

So this book is partially about refactoring and a little bit about Visual Studio 2010. However, the main content that makes this book valuable to me is that it covers a lot of design patterns, software design principles and object-oriented concepts. As an example, check the sample 'Chapter 6 "Improving Class Quality'. It talks about the single responsibility principle and starts refactoring an ugly, tight coupled class into a nice, easy to maintain class with lots of practical tips and sample code.

My recommendation for anyone: must read! Not for the VS2010 refactoring part, but for the design patterns & object-oriented principles clearly explained in the book.

ASP.NET MVC 3 and MEF sitting in a tree...

As I stated in a previous blog post: ASP.NET MVC 3 preview 1 has been released! I talked about some of the new features and promised to do a blog post in the dependency injection part. In this post, I'll show you how to use that together with MEF.

Download my sample code: Mvc3WithMEF.zip (256.21 kb)

kick it on DotNetKicks.com

Dependency injection in ASP.NET MVC 3

First of all, there’s 4 new hooks for injecting dependencies:

  • When creating controller factories
  • When creating controllers
  • When creating views (might be interesting!)
  • When using action filters

In ASP.NET MVC 2, only one of these hooks was used for dependency injection: a controller factory was implemented, using a dependency injection framework under the covers. I did this once, creating a controller factory that wired up MEF and made sure everything in the application was composed through a MEF container. That is, everything that is a controller or part thereof. No easy options for DI-ing things like action filters or views…

ASP.NET MVC 3 shuffled the cards a bit. ASP.NET MVC 3 now contains and uses the Common Service Locator’s IServiceLocator interface, which is used for resolving services required by the ASP.NET MVC framework. The IServiceLocator implementation should be registered in Global.asax using just one line of code:

[code:c#]

MvcServiceLocator.SetCurrent(new SomeServiceLocator());

[/code]

This is, since ASP.NET MVC 3 preview 1, the only thing required to make DI work. In controllers, in action filters and in views. Cool, eh?

Leveraging MEF with ASP.NET MVC 3

First of all: a disclaimer. I already did posts on MEF and ASP.NET MVC before, and in all these posts, I required you to explicitly export your controller types for composition. In this example, again, I will require that, just for keeping code a bit easier to understand. Do note that are some variants of a convention based registration model available.

As stated before, the only thing to build here is a MefServiceLocator that is suited for web (which means: an application-wide catalog and a per-request container). I’ll still have to create my own controller factory as well, because otherwise I would not be able to dynamically compose my controllers. Here goes…

Implementing ServiceLocatorControllerFactory

Starting in reverse, but this thing is the simple part :-)

[code:c#]

[Export(typeof(IControllerFactory))]
[PartCreationPolicy(CreationPolicy.Shared)]
public class ServiceLocatorControllerFactory
    : DefaultControllerFactory
{
    private IMvcServiceLocator serviceLocator;

    [ImportingConstructor]
    public ServiceLocatorControllerFactory(IMvcServiceLocator serviceLocator)
    {
        this.serviceLocator = serviceLocator;
    }

    public override IController CreateController(RequestContext requestContext, string controllerName)
    {
        var controllerType = GetControllerType(requestContext, controllerName);
        if (controllerType != null)
        {
            return this.serviceLocator.GetInstance(controllerType) as IController;
        }

        return base.CreateController(requestContext, controllerName);
    }

    public override void ReleaseController(IController controller)
    {
        this.serviceLocator.Release(controller);
    }
}

[/code]

Did you see that? A simple, MEF enabled controller factory that uses an IMvcServiceLocator. This thing can be used with other service locators as well.

Implementing MefServiceLocator

Like I said, this is the most important part, allowing us to use MEF for resolving almost any component in the ASP.NET MVC pipeline. Here’s my take on that:

[code:c#]

[Export(typeof(IMvcServiceLocator))]
[PartCreationPolicy(CreationPolicy.Shared)]
public class MefServiceLocator
    : IMvcServiceLocator
{
    const string HttpContextKey = "__MefServiceLocator_Container";

    private ComposablePartCatalog catalog;
    private IMvcServiceLocator defaultLocator;

    [ImportingConstructor]
    public MefServiceLocator()
    {
        // Get the catalog from the MvcServiceLocator.
        // This is a bit dirty, but currently
        // the only way to ensure one application-wide catalog
        // and a per-request container.
        MefServiceLocator mefServiceLocator = MvcServiceLocator.Current as MefServiceLocator;
        if (mefServiceLocator != null)
        {
            this.catalog = mefServiceLocator.catalog;
        }

        // And the fallback locator...
        this.defaultLocator = MvcServiceLocator.Default;
    }

    public MefServiceLocator(ComposablePartCatalog catalog)
        : this(catalog, MvcServiceLocator.Default)
    {
    }

    public MefServiceLocator(ComposablePartCatalog catalog, IMvcServiceLocator defaultLocator)
    {
        this.catalog = catalog;
        this.defaultLocator = defaultLocator;
    }

    protected CompositionContainer Container
    {
        get
        {
            if (!HttpContext.Current.Items.Contains(HttpContextKey))
            {
                HttpContext.Current.Items.Add(HttpContextKey, new CompositionContainer(catalog));
            }

            return (CompositionContainer)HttpContext.Current.Items[HttpContextKey];
        }
    }

    private object Resolve(Type serviceType, string key = null)
    {
        var exports = this.Container.GetExports(serviceType, null, null);
        if (exports.Any())
        {
            return exports.First().Value;
        }

        var instance = defaultLocator.GetInstance(serviceType, key);
        if (instance != null)
        {
            return instance;
        }

        throw new ActivationException(string.Format("Could not resolve service type {0}.", serviceType.FullName));
    }

    private IEnumerable<object> ResolveAll(Type serviceType)
    {
        var exports = this.Container.GetExports(serviceType, null, null);
        if (exports.Any())
        {
            return exports.Select(e => e.Value).AsEnumerable();
        }

        var instances = defaultLocator.GetAllInstances(serviceType);
        if (instances != null)
        {
            return instances;
        }

        throw new ActivationException(string.Format("Could not resolve service type {0}.", serviceType.FullName));
    }

    #region IMvcServiceLocator Members

    public void Release(object instance)
    {
        var export = instance as Lazy<object>;
        if (export != null)
        {
            this.Container.ReleaseExport(export);
        }

        defaultLocator.Release(export);
    }

    #endregion

    #region IServiceLocator Members

    public IEnumerable<object> GetAllInstances(Type serviceType)
    {
        return ResolveAll(serviceType);
    }

    public IEnumerable<TService> GetAllInstances<TService>()
    {
        var instances = ResolveAll(typeof(TService));
        foreach (TService instance in instances)
        {
            yield return (TService)instance;
        }
    }

    public TService GetInstance<TService>(string key)
    {
        return (TService)Resolve(typeof(TService), key);
    }

    public object GetInstance(Type serviceType)
    {
        return Resolve(serviceType);
    }

    public object GetInstance(Type serviceType, string key)
    {
        return Resolve(serviceType, key);
    }

    public TService GetInstance<TService>()
    {
        return (TService)Resolve(typeof(TService));
    }

    #endregion

    #region IServiceProvider Members

    public object GetService(Type serviceType)
    {
        return Resolve(serviceType);
    }

    #endregion
}

[/code]

HOLY SCHMOLEY! That is a lot of code. Let’s break it down…

First of all, I have 3 constructors. 2 for convenience, one for MEF. Since the MefServiceLocator will be instantiated in Global.asax and I only want one instance of it to live in the application, I have to do a dirty trick: whenever MEF wants to create a new MefServiceLocator for some reason (should in theory only happen once per request, but I want this thing to live application-wide), I’m giving it indeed a new instance which at least shares the part catalog with the one I originally created. Don’t shoot me for doing this…

Next, you will also notice that I’m using a “fallback” locator, which in theory will be the instance stored in MvcServiceLocator.Default, which is ASP.NET MVC 3’s default MvcServiceLocator. I’m doing this for a reason though… read my disclaimer again: I stated that everything should be decorated with the [Export] attribute when I’m relying on MEF. Now since the services exposed by ASP.NET MVC 3, like the IFilterProvider, are not decorated with this attribute, MEF will not be able to find those. When I find myself in that situation, the MefServiceLocator is simply asking the default service locator for it. Not a beauty, but it works and makes my life easy.

Wiring things

To wire this thing, all it takes is adding 3 lines of code to my Global.asax. For clarity, I’m giving you my entire Global.asax Application_Start method:

[code:c#]

protected void Application_Start()
{
    // Register areas

    AreaRegistration.RegisterAllAreas();

    // Register filters and routes

    RegisterGlobalFilters(GlobalFilters.Filters);
    RegisterRoutes(RouteTable.Routes);

    // Register MEF catalogs

    var catalog = new DirectoryCatalog(
        Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "bin"));
    MvcServiceLocator.SetCurrent(new MefServiceLocator(catalog, MvcServiceLocator.Default));
}

[/code]

Can you spot the 3 lines of code? This is really all it takes to make the complete application use MEF where appropriate. (Ok, that is a bit of a lie since you would still have to implement a very small IFilterProvider if you want MEF in your action filters, but still.)

Hooks

The cool thing is: a lot of things are now requested in the service locator we just created. When browsing to my site index, here’s all the things that are requested:

  • Resolve called for serviceType: System.Web.Mvc.IControllerFactory
  • Resolve called for serviceType: Mvc3WithMEF.Controllers.HomeController
  • Resolve called for serviceType: System.Web.Mvc.IFilterProvider
  • Resolve called for serviceType: System.Web.Mvc.IFilterProvider
  • Resolve called for serviceType: System.Web.Mvc.IFilterProvider
  • Resolve called for serviceType: System.Web.Mvc.IFilterProvider
  • Resolve called for serviceType: System.Web.Mvc.IViewEngine
  • Resolve called for serviceType: System.Web.Mvc.IViewEngine
  • Resolve called for serviceType: ASP.Index_cshtml
  • Resolve called for serviceType: System.Web.Mvc.IViewEngine
  • Resolve called for serviceType: System.Web.Mvc.IViewEngine
  • Resolve called for serviceType: ASP._LogOnPartial_cshtml

Which means that you can now even inject stuff into views or compose their parts dynamically.

Conclusion

I have a strong sense of a power in here… ASP.NET MVC 3 will support DI natively if you want to use it, and I’ll be one of the users happily making use of it. There’s use cases for injecting/composing something in all of the above components, and ASP.NET MVC 3 made this just simpler and more straightforward.

Here’s my sample code with some more examples in it: Mvc3WithMEF.zip (256.21 kb)

Extension methods for PHP

PHP Extension Methods The concept of “extension” methods will be nothing new to this blog’s .NET-related audience. For the PHP-related audience, this is probably something new. Let’s start with the official definition for extension methods: Extension methods enable you to "add" methods to existing types without creating a new derived type, recompiling, or otherwise modifying the original type. Extension methods are a special kind of static method, but they are called as if they were instance methods on the extended type.

Let’s visualize this. Imagine having the following class:

[code:c#]

class HelloWorld
{
    public function sayHello($to = 'World', $from = null)
    {
        $helloString = "Hello, " . $to . "!";
        if (!is_null($from)) {
            $helloString .= " From " . $from;
        }

        echo $helloString . "\r\n";
    }
}

[/code]

Not too difficult. There’s a sayHello() method that allows you to optionally pass who should be greeted and who the greeting is from. Imagine you would like to have a sayHelloTo() method as well, a shortcut to sayHello($to). And some other helper methods that use sayHello() under the hood. Wouldn’t it be nice to have the HelloWorld class concentrating on the real logic and defining the helper/utility functions somewhere else? How about a class named HelloExtensions:

[code:c#]

class HelloWorldExtensions
{
    public static function sayHelloTo(HelloWorld $subject, $name = '')
    {
        $subject->sayHello($name);
    }

    public static function sayHelloFrom(HelloWorld $subject, $name = '')
    {
        $subject->sayHello('World', $name);
    }
}

[/code]

Ok, nice. But this means I should call HelloWorldExtensions::sayHelloTo(‘Maarten’); to use the utility functions, right? Well: no! Not if we implement the concept of extension methods. Let’s see what we can do to HelloWorld in order to make our life easier.

[code:c#]

class HelloWorld
{
    public function sayHello($to = 'World', $from = null)
    {
        $helloString = "Hello, " . $to . "!";
        if (!is_null($from)) {
            $helloString .= " From " . $from;
        }

        echo $helloString . "\r\n";
    }

    public function __call($functionName, $arguments = array())
    {
        // Add an extra parameter
        array_unshift($arguments, $this);

        // Current reflected class
        $reflectedClass = new reflectionObject($this);

        // Find suitable class and function
        $availableClasses = get_declared_classes();
        foreach ($availableClasses as $class) {
            $classDefinition = new ReflectionClass($class);
            $availableMethods = $classDefinition->getMethods();
            foreach ($availableMethods as $method) {
                if ($method->isStatic() && $method->getName() == $functionName) {
                    $availableParameters = $method->getParameters();
                    if ($availableParameters[0]->getClass()->getName() == $reflectedClass->getName()) {
                        $method->invokeArgs(null, $arguments);
                    }
                }
            }
        }
    }
}

[/code]

The magic method __call() is used to look for a class that defines a static method with the first parameter of our type, HelloWorld. This now allows us to write very clean calls to code, as well as simplify our HelloWorld class:

[code:c#]

$helloWorld = new HelloWorld();
$helloWorld->sayHello();
$helloWorld->sayHelloTo('Maarten');
$helloWorld->sayHelloFrom('Maarten');

[/code]

Sweet, no? Can someone get this into the PHP core? I would greatly appreciate it: my classes can focus on functionality and all utility functions that just pass around variables can be defined in a separate class.

MEF will not get easier, it’s cool as ICE

Over the past few weeks, several people asked me to show them how to use MEF (Managed Extensibility Framework), some of them seemed to have some difficulties with the concept of MEF. I tried explaining that it will not get easier than it is currently, hence the title of this blog post. MEF is based on 3 keywords: export, import, compose. Since these 3 words all start with a letter that can be combined to a word, and MEF is cool, here’s a hint on how to remember it: MEF is cool as ICE!

kick it on DotNetKicks.com

Imagine the following:

You want to construct a shed somewhere in your back yard. There’s tools to accomplish that, such as a hammer and a saw. There’s also material, such as nails and wooden boards.

Let’s go for this! Here’s a piece of code to build the shed:

[code:c#]

public class Maarten
{
    public void Execute(string command)
    {
        if (command == “build-a-shed”)
        {
          List<ITool> tools = new List<ITool>
          {
            new Hammer(),
            new Saw()
          };

          List<IMaterial> material = new List<IMaterial>
          {
            new BoxOfNails(),
            new WoodenBoards()
          };

          BuildAShedCommand task = new BuildAShedCommand(tools, material);
          task.Execute();
        }
    }
}

[/code]

That’s a lot of work, building a shed! Imagine you had someone to do the above for you, someone who gathers your tools spread around somewhere in the house, goes to the DIY-store and gets a box of nails, … This is where MEF comes in to place.

Compose

Let’s start with the last component of the MEF paradigm: composition. Let’s not look for tools in the garage (and the attic), let’s not go to the DIY store, let’s “outsource” this task to someone cheap: MEF. Cheap because it will be in .NET 4.0, not because it’s, well, “cheap”. Here’s how the outsourcing would be done:

[code:c#]

public class Maarten
{
    public void Execute(string command)
    {
        if (command == “build-a-shed”)
        {
          // Tell MEF to look for stuff in my house, maybe I still have nails and wooden boards as well
          AssemblyCatalog catalog = new AssemblyCatalog(Assembly.GetExecutingAssembly());
          CompositionContainer container = new CompositionContainer(catalog);

          // Start the job, and ask MEF to find my tools and material
          BuildAShedCommand task = new BuildAShedCommand();
          container.ComposeParts(task);
          task.Execute();
        }
    }
}

[/code]

Cleaner, no? The only thing I have to do is start the job, which is more fun when my tools and material are in reach. The ComposeParts() call figures out where my tools and material are. However, MEF's stable composition promise will only do that if it can find ("satisfy") all required imports. And MEF will not know all of this automatically. Tools and material should be labeled. And that’s where the next word comes in play: export.

Export

Export, or the ExportAttribute to be precise, is a marker for MEF to tell that you want to export the type or property on which the attribute is placed. Really think of it like a label. Let’s label our hammer:

[code:c#]

[Export(typeof(ITool))]
public class Hammer : ITool
{
  // ...
}

[/code]

The same should be done for the saw, the box of nails and the wooden boards. Remember to put a different label color on the tools and the material, otherwise MEF will think that sawing should be done with a box of nails.

Import

Of course, MEF can go ahead and gather tools and material, but it will not know what to do with it unless you give it a hint. And that’s where the ImportAttribute (and the ImportManyAttribute) come in handy. I will have to tell MEF that the tools go on one stack, the material goes on another one. Here’s how:

[code:c#]

public class BuildAShedCommand : ICommand
{
  [ImportMany(typeof(ITool))]
  public IEnumerable<ITool> Tools { get; set; }

  [ImportMany(typeof(IMaterial))]
  public IEnumerable<IMaterial> Materials { get; set; }

  // ...
}

[/code]

Conclusion

Easy, no? Of course, MEF can do a lot more than this. For instance, you can specify that a certain import is only valid for exports of a specific type and specific metadata: I can have a small and a large hammer, both ITool. For building a shed, I will require the large hammer though.

Another cool feature is creating your own export provider (example at TheCodeJunkie.com). And if ICE does not make sense, try the Zoo example.

kick it on DotNetKicks.com

Supporting multiple submit buttons on an ASP.NET MVC view

Multiple buttons on an ASP.NET MVC view A while ago, I was asked for advice on how to support multiple submit buttons in an ASP.NET MVC application, preferably without using any JavaScript. The idea was that a form could contain more than one submit button issuing a form post to a different controller action.

The above situation can be solved in many ways, one a bit cleaner than the other. For example, one could post the form back to one action method and determine which method should be called from that action method. Good solution, however: not standardized within a project and just not that maintainable… A better solution in this case was to create an ActionNameSelectorAttribute.

Whenever you decorate an action method in a controller with the ActionNameSelectorAttribute (or a subclass), ASP.NET MVC will use this attribute to determine which action method to call. For example, one of the ASP.NET MVC ActionNameSelectorAttribute subclasses is the ActionNameAttribute. Guess what the action name for the following code snippet will be for ASP.NET MVC:

[code:c#]

public class HomeController : Controller
{
    [ActionName("Index")]
    public ActionResult Abcdefghij()
    {
        return View();
    }
}

[/code]

That’s correct: this action method will be called Index instead of Abcdefghij. What happens at runtime is that ASP.NET MVC checks the ActionNameAttribute and asks if it applies for a specific request. Now let’s see if we can use this behavior for our multiple submit button scenario.

kick it on DotNetKicks.com

The view

Since our view should not be aware of the server-side plumbing, we can simply create a view that looks like this.

[code:c#]

<%@ Page Language="C#" Inherits="System.Web.Mvc.ViewPage<MvcMultiButton.Models.Person>" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
    <title>Create person</title>
    <script src="<%=Url.Content("~/Scripts/MicrosoftAjax.js")%>" type="text/javascript"></script>
    <script src="<%=Url.Content("~/Scripts/MicrosoftMvcAjax.js")%>" type="text/javascript"></script>
</head>
<body>

    <% Html.EnableClientValidation(); %>
    <% using (Html.BeginForm()) {%>

        <fieldset>
            <legend>Create person</legend>
            <p>
                <%= Html.LabelFor(model => model.Name) %>
                <%= Html.TextBoxFor(model => model.Name) %>
                <%= Html.ValidationMessageFor(model => model.Name) %>
            </p>
            <p>
                <%= Html.LabelFor(model => model.Email) %>
                <%= Html.TextBoxFor(model => model.Email) %>
                <%= Html.ValidationMessageFor(model => model.Email) %>
            </p>
            <p>
                <input type="submit" value="Cancel" name="action" />
                <input type="submit" value="Create" name="action" />
            </p>
        </fieldset>

    <% } %>

    <div>
        <%=Html.ActionLink("Back to List", "Index") %>
    </div>

</body>
</html>

[/code]

Note the two submit buttons (namely “Cancel” and “Create”), both named “action” but with a different value attribute.

The controller

Our controller should also not contain too much logic for determining the correct action method to be called. Here’s what I propose:

[code:c#]

public class HomeController : Controller
{
    public ActionResult Index()
    {
        return View(new Person());
    }

    [HttpPost]
    [MultiButton(MatchFormKey="action", MatchFormValue="Cancel")]
    public ActionResult Cancel()
    {
        return Content("Cancel clicked");
    }

    [HttpPost]
    [MultiButton(MatchFormKey = "action", MatchFormValue = "Create")]
    public ActionResult Create(Person person)
    {
        return Content("Create clicked");
    }
}

[/code]

Some things to note:

  • There’s the Index action method which just renders the view described previously.
  • There’s a Cancel action method which will trigger when clicking the Cancel button.
  • There’s a Create action method which will trigger when clicking the Create button.

Now how do these last two work… You may also have noticed the MultiButtonAttribute being applied. We’ll see the implementation in a minute. In short, this is a subclass for the ActionNameSelectorAttribute, triggering on the parameters MatchFormKey and MatchFormValues. Now let’s see how the MultiButtonAttribute class is built…

The MultiButtonAttribute class

Now do be surprised of the amount of code that is coming…

[code:c#]

[AttributeUsage(AttributeTargets.Method, AllowMultiple = false, Inherited = true)]
public class MultiButtonAttribute : ActionNameSelectorAttribute
{
    public string MatchFormKey { get; set; }
    public string MatchFormValue { get; set; }

    public override bool IsValidName(ControllerContext controllerContext, string actionName, MethodInfo methodInfo)
    {
        return controllerContext.HttpContext.Request[MatchFormKey] != null &&
            controllerContext.HttpContext.Request[MatchFormKey] == MatchFormValue;
    }
}

[/code]

When applying the MultiButtonAttribute to an action method, ASP.NET MVC will come and call the IsValidName method. Next, we just check if the MatchFormKey value is one of the request keys, and the MatchFormValue matches the value in the request. Simple, straightforward and re-usable.

kick it on DotNetKicks.com

Book review: Zend Framework 1.8 Web Application Development

Zend Framework 1.8 Web Application Development My book shelf is starting to look a lot like the warehouse of Packt Publishing: I’ve received yet another book from them. Different from all previous reviews I did: this one is a PHP book, titled “Zend Framework 1.8 Web Application Development” by Keith Pope.

A chapter overview:

  • Chapter 1: Creating a Basic MVC Application
  • Chapter 2: The Zend Framework MVC Architecture
  • Chapter 3: Storefront Basic Setup
  • Chapter 4: Storefront Models (great chapter!)
  • Chapter 5: Implementing the Catalog
  • Chapter 6: Implementing User Accounts
  • Chapter 7: The Shopping Cart
  • Chapter 8: Authentication and Authorization
  • Chapter 9: The Administration Area
  • Chapter 10: Storefront Roundup
  • Chapter 11: Storefront Optimization
  • Chapter 12: Testing the Storefront

Let’s also state the obvious: Zend Framework evolves much faster than publishers. The framework is now at 1.9.6, while the book covers 1.8.0. Do not let this stop you from reading this book! Let me explain why…

  1. The book covers all concepts and components in the Zend Framework in a full-blown application that is built up from scratch.
  2. Next to that, Keith Pope focuses a lot on the application design, using interfaces, unit testing, mocking, dependency injection, … Want to learn a lot about good application design? Then this is the number one reason to read this book!

These 2 points actually summarize the whole book. Great read, great content and a must-read for everyone who is not completely sure about his application design skills. Congratulations, Keith!

ASP.NET MVC Chained Controller Factory

My last post on the REST for ASP.NET MVC SDK received an interesting comment… Basically, the spirit of the comment was: “There are tons of controller factories out there, but you can only use one at a time!”. This is true. One can have an IControllerFactory for MEF, for Castle Windsor, a custom one that creates a controller based on the current weather, … Most of the time, these IControllerFactory  implementations do not glue together… Unless you chain them!

kick it on DotNetKicks.com

Chaining IControllerFactory

The ChainedControllerFactory that I will be creating is quite easy: it builds a list of IControllerFactory instances that may be able to create an IController and asks them one by one to create it. The one that can create it, will be the one that delivers the controller. In code:

[code:c#]

public class ChainedControllerFactory : IControllerFactory
{
    const string CHAINEDCONTROLLERFACTORY = "__chainedControllerFactory";

    protected List<IControllerFactory> factories = new List<IControllerFactory>();

    public ChainedControllerFactory Register(IControllerFactory factory)
    {
        factories.Add(factory);
        return this;
    }

    public IController CreateController(RequestContext requestContext, string controllerName)
    {
        IController controller = null;
        foreach (IControllerFactory factory in factories)
        {
            controller = factory.CreateController(requestContext, controllerName);
            if (controller != null)
            {
                requestContext.HttpContext.Items[CHAINEDCONTROLLERFACTORY] = factory;
                return controller;
            }
        }

        return null;
    }

    public void ReleaseController(IController controller)
    {
        IControllerFactory factory =
            HttpContext.Current.Items[CHAINEDCONTROLLERFACTORY] as IControllerFactory;
        if (factory != null)
            factory.ReleaseController(controller);
    }
}

[/code]

We have to register this one as the default IControllerFactory in Global.asax.cs:

[code:c#]

protected void Application_Start()
{
    ChainedControllerFactory controllerFactory = new ChainedControllerFactory();
    controllerFactory
        .Register(new DummyControllerFactory())
        .Register(new OnlyHomeControllerFactory())
        .Register(new DefaultControllerFactory());

    ControllerBuilder.Current.SetControllerFactory(controllerFactory);

    RegisterRoutes(RouteTable.Routes);
}

[/code]

Note: the DummyControllerFactory and the OnlyHomeControllerFactory are some sample, stupid IControllerFactory implementations.

Caveats

There is actually one caveat to know when using this ChainedControllerFactory: not all controller factories out there follow the convention of returning null when they can not create a controller. The ChainedControllerFactory expects null to determine if it should try the next IControllerFactory in the chain.

Download source code

You can download example source code here: MvcChainedControllerFactory.zip (244.37 kb) (sample uses MVC 2, code should work on MVC 1 as well)

kick it on DotNetKicks.com

Book review: ASP.NET 3.5 CMS Development

ASP.NET 3.5 CMS Development From time to time, the people at Packt Publishing send me a free book, fresh of the presses, and ask nicely if I want to read it and write a review on my blog. Last week, I received their fresh ASP.NET 3.5 CMS Development book, written by Curt Christianson and Jeff Cochran, both Microsoft MVP (ASP.NET and IIS).

According to the website, the book aims at learning people how to build a CMS. Now, I know from writing my ASP.NET MVC 1.0 Quickly book that these texts are written mostly by marketing people.

This step-by-step tutorial shows the reader how to build an ASP.NET Content Management System from scratch. You will first learn the basics of a content management system and how to set up the tools you need to build your site. Then, you start building your site, setting up users, and adding content to your site. You will be able to edit the content of your site and also manage its layout all by yourself. Towards the end, you will learn to manage your site from a single point and will have all the information you need to extend your site to make it more powerful.

Filled with plenty of code snippets and screen images to keep you on track as well as numerous additional samples to show you all the exciting alternatives to explore, this book prepares you for all the challenges you can face in development. 

Ok, it is true: this book will show you how to build a content management system in ASP.NET 3.5. However, if you are a developer working with ASP.NET for several years and the CMS part is the reason you are buying this book, you will be a bit disappointed. Don’t get me wrong, the book is good for another audience: if you are making your first steps in ASP.NET development and want to learn how things like datasources, n-tier development, membership provider, extensibility, … work, by example, this book is actually pretty good at that. Curt and Jeff managed to squeeze in about all commonly used ASP.NET features using only one example application that is built from ground up.

Conclusion: probably not the book for experienced developers, but an ideal “large, example-driven tutorial” for beginning development with ASP.NET 3.5.

Book review: ASP.NET 3.5 Social Networking

image Last week, I found another book from Packt in my letterbox. This time, the title is ASP.NET 3.5 Social Networking, written by Andrew Siemer.

On the back cover, I read that this book shows you how to create a scalable, maintainable social network that can support hundreds of thousands of users, multimedia features and stuff like that. The words scalable and maintainable seem to have triggered me: I started reading ASAP. The first chapter talks about what a social network is and proposes a new social network: Fisharoo.com, a web site for salt water aquarium fanatics, complete with blogs, forums, personal web sites, …

The book starts by building a framework containing several features such as logging, mail sending, …, all backed-up by a dependency injection framework to enable fast replacement of several components. Afterwards, each feature of the Fisharoo.com site is described in a separate chapter: what is the feature, how will we store data, what do we need to do in our application to make it work?

A good thing about this book is that it demonstrates several concepts in application design using a sample application that anyone who has used a site like Facebook is familiar with. The concepts demonstrated are some that any application can benefit from: Domain Driven Design, Test Driven Design (TDD), Dependency Injection, Model-View-Presenter, … Next to this, some third-party components like Lucene.NET are demonstrated. This all is very readable and understandable, really a must-read for anyone interested in these concepts!

Bottom line of the story: it has been a while since I was enthousiast about a book, and this one clearly made me enthousiast. Sure, it describes stuff about building a social network, but I think that is only a cover for what this book is really about: building good software that is easy to maintain, test and extend.

Book review: ASP.NET 3.5 Application Architecture and Design

image The people at Packt asked it again: “Do you want to review this book?” Sure I do! The book I’m reviewing this time is ASP.NET 3.5 Application Architecture and Design, written by Vivek Thakur.

Application Architecture is always an interesting topic to read on. Different people have different opinions, there is no one perfect solution to a problem, … This book covers application architecture, applied to ASP.NET, although these concepts can be applied in any application. Questions like “What are tiers?” and “How do you structure an application?” are dug into in the first few chapters. The next chapters focus on more specific areas of application architecture: the domain model, UML, creating an ER diagram, SOA, the ASP.NET MVC framework, … Each of these concepts is explained using a single project example, which makes it easy to see the differences, pro’s and con’s of a certain solution.

To be honest, I don’t think this book is something for experienced architects or lead developers. More experienced architects will probably remain a little bit hungry because large, complex, real-world architectures are not covered or illustrated. The book covers all concepts of application architecture using a simple example, which makes them clear to any developer who is interested in architecture but has always been affraid of all these concepts.

If you are familiar with the words “N-Tier”, “domain model” and other architectural concepts, I think this book might not be covering architecture deep enough. Are you a developer wanting to release some open-source software? Unaware of the concepts mentioned? Then read this book as it is a great starter book.