Posts in  csharp

2.25.2010

Sexy Windsor Registrations

After working with FluentNHibernate and seeing examples of registries in StructureMap, I started craving the same thing for my registrations with Windsor. Our registrations often look like the following:

public static void Register(IWindsorContainer container)
{
  container.Register(Component.For<IFoo>().ImplementedBy<Foo>());
  container.AddComponent<IFoo, Foo>();
  ...
}

There are a few things I don’t like about this approach:

  1. Passing a container around through static methods is a hack.
  2. Ceremony of “container.” calls clutter the registry and impede readability.
  3. Why do I need so much ceremony to get to Component.For? “container.Register(Component.For” is tedious!

Note: this code is available on github. The registries are tested with nunit, so you can drop in whatever version of windsor and verify it works.

IWindsorInstaller to the static rescue

A registry needs a uniform entry point. Enter IWindsorInstaller, a rather undocumented feature that deserves more attention.

 public interface IWindsorInstaller
  {
    void Install(IWindsorContainer container, IConfigurationStore store);
  }

  // Container entry point
  container.Install(IWindsorInstaller installer);

The container has an install method that takes an instance of IWindsorInstaller. See this post for more details about IWindsorInstaller.

Adapting to Component.For

Now to fix readability, what if we could:
  public class SampleRegistry : RegistryBase
  {
    public SampleRegistry()
    {
      For<IFoo>().ImplementedBy<Foo>().LifeStyle.Singleton();
      For<IFoo>().ImplementedBy<Foo>();
    }
  }
To pull this off, the RegistryBase keeps a collection of registrations and adapts to the Component.For entry point to capture the registration before returning it. These registrations are stored in a Steps collection, more on why this isn't called Registrations later.
  public class RegistryBase : IWindsorInstaller
  {
    ...

    public ComponentRegistration<S> For<S>()
    {
      var registration = Component.For<S>();
      Steps.Add(registration);
      return registration;
    }

    public ComponentRegistration<S> For<S, F>()
    {
      var registration = Component.For<S, F>();
      Steps.Add(registration);
      return registration;
    }

    public ComponentRegistration<S> For<S, F1, F2>()
    {
      var registration = Component.For<S, F1, F2>();
      Steps.Add(registration);
      return registration;
    }

    public ComponentRegistration<S> For<S, F1, F2, F3>()
    {
      var registration = Component.For<S, F1, F2, F3>();
      Steps.Add(registration);
      return registration;
    }

    public ComponentRegistration<S> For<S, F1, F2, F3, F4>()
    {
      var registration = Component.For<S, F1, F2, F3, F4>();
      Steps.Add(registration);
      return registration;
    }

    public ComponentRegistration For(params Type[] types)
    {
      var registration = Component.For(types);
      Steps.Add(registration);
      return registration;
    }
    ...
  }

Installation

RegistryBase implements the IWindsorInstaller.Install method to add registrations to the container.

  public virtual void Install(IWindsorContainer container, IConfigurationStore store)
  {
    Steps.ForEach(s => container.Register(s));
  }

The application bootstrapper adds registries. This example assumes all registries are loaded into the container, though they probably would never have dependencies (chicken/egg paradox). I just like to abuse my container :)

  private static void LoadRegistries(IWindsorContainer container)
  {
    var registries = container.ResolveAll<IWindsorInstaller>();
    registries.ForEach(r => container.Install(r));
  }

Other adaptations

The registry also adapts to a few other entry points and captures their registrations.

  1. container.AddComponent
  2. container.AddFacility
  3. AllTypes.FromAssemblyNamed
  4. AllTypes.FromAssembly
  5. AllTypes.FromAssemblyContaining

Adapting to the unknown

In the event there is an entry point missing from the registry, it has a Custom method that takes an Action. This allows for access to the container as usual. This is captured as a deferred action that won't be executed until the registry is installed in the container. Hence the name "Steps" for registrations and custom actions.

Show me the money

Here is a sample of different useages of the registry, of course the entire fluent registration API is at your finger tips.

  public class SampleRegistry : RegistryBase
  {
    public SampleRegistry()
    {
      // Register a singleton
      For<IFoo>().ImplementedBy<Foo>().LifeStyle.Singleton(); // Extension methods to call property.

      // Register a single item
      For<IFoo>().ImplementedBy<Foo>();
      For(typeof (IFoo)).ImplementedBy<Foo>();
      AddComponent<IFoo, Foo>();

      // Custom actions if you want to access the original container API, with deferred installation via lambda expressions
      Custom(c => c.AddComponent<IFoo, Foo>());
      Custom(c => c.Register(Component.For<IFoo>().ImplementedBy<Foo>()));

      // Scan for types
      FromAssemblyContaining<SampleRegistry>().BasedOn<IFoo>();
      FromAssemblyContaining(typeof (SampleRegistry)).BasedOn<IFoo>();
      FromAssemblyNamed("GotFour.Windsor.Tests").BasedOn<IFoo>();
      FromAssembly(typeof (SampleRegistry).Assembly).BasedOn<IFoo>();

      // Forwarding types
      For<IFoo, Foo>().ImplementedBy<Foo>();
      For<IFoo, Foo, FooBar>().ImplementedBy<FooBar>();
      For<IFoo, Foo, FooBar, FooBar2>().ImplementedBy<FooBar2>();
      For<IFoo, Foo, FooBar, FooBar2, FooBar3>().ImplementedBy<FooBar3>();

      // Adding facilities
      AddFacility<StartableFacility>();
    }
  }

Notes: I have tested capturing registrations for all of the above scenarios but I suppose there might be some deep dark portion of the registration API that might not work. This would happen if something creates a brand new registration, independent of the original captured one. I have yet to run into this, the design of the api is pretty rock solid as a builder that collects state. I left out AllTypes.Of.From since Of doesn't return a registration, it is simply a call to AllTypes.FromAssemblyXyz().BasedOn() reversed and really isn't very helpful.

ExtendedRegistryBase : RegistryBase

I added an extended set of registration points with ExtendedRegistryBase. This adds another layer of new fluent registrations for common scenarios, often involving convention based registration :) If you have additions, please add them in the comments and I will get them added.

  public class SampleExtendedRegistry : ExtendedRegistryBase
  {
    public SampleExtendedRegistry()
    {
      // Same as scanning above in SampleRegistry but much cleaner!
      ScanMyAssemblyFor<IFoo>();

      // Scan for all services of the pattern Service : IService
      ScanMyAssembly(Conventions.FirstInterfaceIsIName);

      // Scan for all services of the pattern Whatever : IService (register with first interface)
      ScanMyAssembly(Conventions.FirstInterface);

      // Next we could use some attributes to discover services, to register imports / exports :)
    }
  }

This registry class helps avoid the static calls to registries from my applications. Now I can scan for registries of a known type and install them into the container. The registries are much more readable with the ceremony gone. I know there was talk of adding something like this to the next version of Windsor/MicroKernel. I hope this is the direction that effort is headed towards. In the mean time enjoy this as a fix to the cravings for a cleaner registry. I typically add one of these per project and let it control registration within that layer.


Shout it

kick it on DotNetKicks.com

-Wes

11.25.2009

Remove<T>(this IList<T> source, Func<T,bool> selector) why not?

Maybe I am just crazy, but it seems like removing or deleting items from a collection is always an after thought. Take IList for example, a list of items, with the ability to add and remove from it. We have a flurry of extension methods that are inherited from IEnumerable to add items but it seems like no one thought maybe it would be nice to beef up the remove method with some extension methods. Maybe I missed an extension namespace, maybe I am just crazy. How many times do we have to write the following bloated code just to remove something from a collection?

var ingredient = Ingredients.FirstOrDefault(i => i.FeedId == feed.Id);
Ingredients.Remove(ingredient);

Even worse, is when we want to remove multiple items from a list based on some criteria. I have to add a foreach loop of some sort to remove each item one at a time. Oh and, deal with the always wonderful: (System.InvalidOperationException: Collection was modified; enumeration operation may not execute). So, I have to remember to create a new list to avoid this dreadful mistake:

var ingredients = Ingredients.Where(i => i.FeedId == feed.Id).ToList();
foreach (var ingredient in Ingredients)
{
  Ingredients.Remove(ingredient);
}

Of course, now that I have created a new list, ToList(), I can simplify this to:

var ingredients = Ingredients.Where(i => i.FeedId == feed.Id).ToList();
ingredients.ForEach(i=> Ingredients.Remove(i));

But that is still icky, all that code just to remove an item or a set of items? So enough complaining on my part, it's time to put up or shut up. This is what I want to do in code:

Ingredients.Remove(i => i.FeedId == feed.Id);

Simple, right? And to do this here is the simple extension method:

public static void Remove<T>(this IList<T> source, Func<T, bool> selector)
{
  if (source == null || selector == null)
  {
    return;
  }

var itemsToRemove = source.Where(selector).ToList(); itemsToRemove.ForEach(i => source.Remove(i)); }

Now, I no longer have to worry about all these things when I want to remove items based on searching my list:

  • Doing a separate search for the items I want to remove
  • Creating a new list, avoiding the pitfall of enumerating when removing and getting "Collection was modified" exceptions.
  • Iterating over those items and calling remove on each

Some purists out there would be mad that I just quietly allow the source/selector to be null and not throw an exception. That's how I chose to implement this, if you want different behavior that's great. Just make sure you add this extension method to your arsenal! Maybe another RemoveSingle that throws an exception if it finds 0 or more than 1 item would be appropriate to add as well?

Happy coding!

9.24.2009

The slippery slope of "var"

The var keyword has been a rather controversial addition to the C# language. Many developers initially fear it, getting lost in demos that use it. Eventually, they come to understand it as something "lazy" programmers would use and often dismiss it. I've gone through these stages. I even remember my blood boiling when I saw resharper, out of the box, suggest to use it! I never really understood it as anything more than implicit typing.

Recently, I decided that I should learn new concepts with new languages instead of just trying to learn and do examples in the same old. Why not kill two birds with one stone! I've been exploring a lot of interpreted languages (functional and imperative), focusing on Scheme (LISP) and python. I've had a great joy reading and conceptualizing new things in these language.

Studying new concepts and applying them with dynamic languages has made me notice, more than ever, all the boiler plate type code to get anything done in C#. After a weekend of hacking in python, I find myself skipping type declarations in C# only to get compiler errors :(. The simplicity of

names = ('Bob', 'John')
in python is doubled in C# to
List<string> names = new List<string>{ "Bob", "John" };
without any added value!

I have been struggling to find ways to bring this simplicity to C#, short of switching to python altogether :). My favorite way is to cut some of the crap and go with
var names = new List<string>{ "Bob", "John" };
. No loss of information and some added clarity! However, the use of var is often frowned upon as if it were unprofessional, my peers reading my latest code only to comment on my "abuse" of it!

What I was missing is the next step in the progression of understanding var. I was starting to realize that it adds clarity through readability! No longer do I have to scan through a bunch of type verbiage in a variable declaration to find the name, let alone the content. Readability alone wasn't convincing my critics so I pondered on the topic some more in regards to another set of concepts I have been working to grasp, DDD.

In studying DDD (Domain Driven Design) I detected a sense of deja vu. The core concepts, of creating a ubiquitous language and model that permeates code, was resonating all the way down to the level of variables. If a variable represents a list of employee names, it should be labeled employeeNames. If we cram that much intent and meaning into our variable names, why do we even care what primitive or compound type is used?

employeeNames might be implemented as a List<string> in C# or a simple list in python. However, when all is said and done, employeeNames is neither a List<string> in C# nor a list in python. Thinking about it as such adds no value, just translation overhead. employeeNames is simply a variable to store employee names, it's type is employeeNames! The name implies this directly. It describes a kind of name, employee, and it's plural, clearly a collection or set of names. The same would apply for a variable to represent age, even if implemented as an integer, it's not an integer, it is an age!

I think this is the answer to help convince people that using var is actually a good thing. Especially when writing unit tests where readability is a primary concern. I would even go so far as to suggest using it anywhere when declaring a variable. The only argument I have heard against this, thus far, is that this will lead to ambiguity. But wait a minute, I think the opposite is true! Static typing leaves room for intention to be left in the type itself. Because of this, developers get sloppy with variable names. When developers don't have a type to prefix a variable, they typically put more intention into the name, for their own sanity!

I would be more inclined to believe I would run across
List<string> employees = new List<string>();
in C# than
employees = ('Bob', 'John')
in python. This example requires knowledge that employees is implemented as a list of strings for someone to extrapolate that employees holds names and not ages or something else. However, with a list of strings, this may just be a guess! It could be a list of their emails or maybe home addresses! I know I've seen this in the past and I know I've done it myself. This added translation only decreases the maintainability of the code.

So the next evolution, in the slope of understanding and using var will be understanding it as a tool of readability and to help avoid leaving intention in types. This adds a layer of linguistic abstraction that hides the implementation of our variable's type and makes it more flexible.

I think the last evolution with var, will be to help developers get more familiar with the ideas behind dynamic typing. Implicit typing is like a step in the direction of dynamic typing. The last thing to do, seems to be to drop the use of var at all. It's simply linguistic boilerplate to developers (even if it serves a purpose to the C# evaluator).

So get your var on, don't be ashamed!