Showing posts with label patterns. Show all posts
Showing posts with label patterns. Show all posts

Saturday, June 18, 2011

Isolating custom Library dependencies versions from consumer dependency versions

This post is more about the CLR and dependency management than it is about Rx. However at this point in Rx’s lifecycle it seems relevant to comment on. The same principles could obviously be applied to open source projects et. al.

I have recently heard of an interesting situation that no-doubt has proved troublesome to people before. This problem is particularly interesting with Rx and it’s recent rate of versions. If you are trying to incorporate Rx into a library of yours and you then want to publish that library, you are effectively forcing users to use the same version of Rx that you do. Considering that a version of Rx comes out say every two months and that often there are breaking changes, this can create quite a mess. It is also made more interesting that up until recently they have not specified if a release was experimental or considered stable.

To provide an example to better understand my particular point; imagine you have a library that wraps a messaging platform. You want to avoid the use of Events and APM, and expose things via IObservable<T>. You feel happy that IObservable<T> is exposed natively in .NET 4 so you should not have to expose your implementations of Rx. You do however, want to use Rx as it has features you need and don’t want to (re-)write yourself. Your standard approaches to package/deployment are:

  • deploy the parts of the Rx libraries you use with your code. Users can just put them all into a “lib\MyFramework” folder and reference them.
  • excluded the libraries from your code and set Specific Version = False and hope your code will work with the consumer’s version of Rx
  • use a package management tool like Nuget to publish your package and specify the valid versions of Rx your library will work with.
  • rely on things being in the GAC so you can utilise the side-by-side versioning it provides
  • just try and implement the parts of Rx you want and avoid DLL Hell.

I gave this some thought and I think I have come up with a solution that could help library authors protect themselves. While there is the obvious option of using Nuget as part of your dependency management, this does not solve the problem, it just eases the pain. If the customer wants to use the latest version of Rx and you only support the 3 previous versions, your customer is still in some trouble.

The theory i had was that I can specify the specific version of Rx I want to reference in my library, the problem being that it may be named the same as the client’s referenced version. Depending on where their references were built to, they could overwrite each other. It seemed the solution was to embed the dependency into my library.

This turns out to actually be quite easy. If you have a project in visual studio that references your version of Rx, you have to follow these steps:

  1. Ensure you have a file reference (not a project or a GAC reference) to the dependency, in this case System.Reactive.dll
  2. Set the reference to be Specific Version = True
  3. Set the reference Copy Local = False
  4. Embed the dependency into your library. I created a folder in my project called EmbeddedAssemblies. I “Add Existing…” to this folder, navigate to the dependencies (just System.Reactive.dll in this case), and then choose “Add as Link…
  5. Set the “Build Action” of  the newly added link to Embedded Resource
  6. Ensure that the resource is loaded correctly at run time…

The last part of that list proves to be not too hard. You can hook on to the AppDomain.AssemblyResolve event and load your embedded resource. You can return your embedded dependency by reading the byte stream and creating the assembly from it and then returning that in the event handler

internal static class DependencyResolver
{
  private static int _isSet = 0;

  internal static void Ensure()
  {
    if (Interlocked.CompareExchange(ref _isSet, 1, 0) == 0)
    {
      var thisAssembly = Assembly.GetExecutingAssembly();
      var assemblyName = new AssemblyName(thisAssembly.FullName).Name;
      var embededAssemblyPrefix = assemblyName + ".EmbeddedAssemblies.";

      var myEmbeddedAssemblies =
        Assembly.GetExecutingAssembly().GetManifestResourceNames()
          .Where(name => name.StartsWith(embededAssemblyPrefix))
          .Select(resourceName =>
                    {
                      using (var stream = Assembly.GetExecutingAssembly().GetManifestResourceStream(resourceName))
                      {
                        var assemblyData = new Byte[stream.Length];
                        stream.Read(assemblyData, 0, assemblyData.Length);
                        return Assembly.Load(assemblyData);
                      }
                    })
          .ToDictionary(ass => ass.FullName);

      AppDomain.CurrentDomain.AssemblyResolve += (sender, args) =>
                                                    {
                                                      Assembly assemblyToLoad = null;
                                                      myEmbeddedAssemblies.TryGetValue(args.Name, out assemblyToLoad);
                                                      return assemblyToLoad;
                                                    };
    }
  }
}

You can return null in the event handler to say I don't know how to load this assembly. This allows others to be able to have a go at loading the assembly in the same way.

Next, to ensure that my embedded dependency resolver is called, I opted to make a call to it in the static constructor of the key types in my library. eg

public class SomeProvider
{
  static SomeProvider()
  {
    DependencyResolver.Ensure();
  }

  //other stuff goes here...
}

Have a look at the example code by downloading this zip file

Caveats : This is a thought and the code and concepts are only demo quality. I have not used this in production quality code. I also have not verified that the license allows for this style of packaging.

Further links:

Friday, August 14, 2009

How not to write an Interface in C# 3.0

While working with the IUnityContainer interface from Microsoft's Patterns and Practices team, I decided that it was well worth a post on how not to design interfaces. Recent discussion amongst Rhys and Colin (here as well) have been interesting but I imagine most would agree that both arguments are probably fighting over which polish to use on their code. If these are the big battles you have to face at work then I am jealous.

Introducing IUnityContainer ....
42 members are defined on this interface. Fail.
With much restraint I wont go on about it and flame the guys who write it. Most people know of my disdain for the P&P team at Microsoft. So what tips do I give to make this a usable again? Lets break down the solution into a few tips:

  • Extension methods
  • Cohesion
  • Intention revealing interfaces

How do each of these help us. Let look at some code I was writing pre-extension methods. It was a validation interface that had 2 methods, Validate and Demand

public interface IValidator<T>
{
  IEnumerable<ValidationErrors> Validate(T item);

  ///<exception cref="ValidationException">Thrown when the item is not valid</exception>
  void Demand(T item);
}

The problem with this interface is that all implementations of the interface would/could implement Demand the same way; Make a call to Validate(T item) and if any ValidationErrors came back throw an exception with the validation failures. Time ticks by and I realise the now that I have extension methods in C# 3.0 (.NET 3.5). I only need to have the Validate method on my interface now and provide the Demand implementation as an extension method. The code now becomes:

public interface IValidation<T>
{
  /// <summary>
  /// Validates the specified item, returning a collection of validation errors.
  /// </summary>
  /// <param name="item">The item to validate.</param>
  /// <returns>Returns a <see cref="T:ArtemisWest.ValidationErrorCollection"/> that is empty for a valid item, 
  /// or contains the validation errors if the item is not in a valid state.</returns>
  /// <remarks>
  /// Implementations of <see cref="T:ArtemisWest.IValidation`1"/> should never return null from the validate method.
  /// If no validation errors occured then return an empty collection.
  /// </remarks>
  IEnumerable<ValidationErrors> Validate(T item);
}
public static class ValidatorExtensions
{
  /// <summary>
  /// Raises a <see cref="T:ArtemisWest.ValidationException"/> if the <paramref name="item"/> is not valid.
  /// </summary>
  /// <typeparam name="T">The type that the instance of <see cref="T:IValidation`1"/> targets.</typeparam>
  /// <param name="validator">The validator.</param>
  /// <param name="item">The item to be validated.</param>
  /// <exception cref="T:ArtemisWest.ValidationException">
  /// Thrown when validating the <paramref name="item"/> returns any errors. Only the first 
  /// validation error is raised with the exception. Any validation errors that are marked as
  /// warnings are ignored.
  /// </exception>
  public static void Demand<T>(this IValidation<T> validator, T item)
  {
    foreach (var error in validator.Validate(item))
    {
      if (!error.IsWarning)
      {
        throw new ValidationException(error);
      }
    }
  }
}

Then end result is that the API feels the same as I have access to both methods, but the cost of implementing my interface is reduced to just its core concern.
So, extension methods is one trick we have in the bag. Next cohesion.

The recent discussion between Rhys and Colin is "how many members belong on an interface?" I think both will agree that answer is not 42. Juval Lowy made a great presentation at TechEd2008 on Interfaces and that we should be aiming for 3-7 members per interface. This provides us with a level of cohesion and a low level of coupling. Lets look at some of the members on the IUnityContainer Interface.

  • 8 overloads of RegisterInstance
  • 16 overloads of RegisterType
  • Add/Remove "Extensions" methods
  • 4 overloads of BuildUp
  • 2 overloads of ConfigureContainer
  • CreateChildContainer
  • 4 overloads of Resolve
  • 2 overloads of ResolveAll
  • A TearDown method
  • and a Parent property
Whew! Well how can we tame this beast? When I look at this interface I see certain groups that look like they are related in usage. They would be the
  1. Register and Resolve functionality
  2. And and Remove extensions functionality
  3. Build up and teardown functionality
  4. Container hierarchy functionality (Parent and CreateChildContainer)
  5. Container configuration


Interestingly on our current project we only use the Register/Resolve functionality.
These five groups to me have some level of cohesion. That to me then makes them a candidate for there own interfaces. The big giveaway being that I use unity quite successfully but never use 4/5 of the functionality defined on this interface. So our 2nd tip would be to split out these groups on functionality into there own interfaces.
But what do we name the new interfaces? This is our 3rd tip:

Intention revealing interfaces.

Looking at my list I would imagine some useful names could be:

  1. IContainer
  2. IExtensionContainer
  3. ILifecycleContainer
  4. INestedContainer
  5. IConfigurableContainer
To be honest, I have put little thought into these names. Normally I would put a LOT of effort into getting the naming right, but I don't work on the P&P team so these changes will never be done so why waste my time? Edit: My laziness here really does take the wind our of the sails of this argument. Sorry.
Ok so how can we bring this all together? My proposal would be to have 6 interfaces
  1. IContainer
  2. IExtensionContainer
  3. ILifecycleContainer
  4. INestedContainer
  5. IConfigurableContainer
  6. IUnityContainer : IContainer, IExtensionContainer, ILifecycleContainer, INestedContainer, IConfigurableContainer


Next I would create some extension methods to deal with the silly amount of duplication the multiple overloads incur. Looking at the implementation in UnityContainerBase I would think that all of these methods could be candidates for extension methods

public abstract class UnityContainerBase : IUnityContainer, IDisposable
{
  //prior code removed for brevity
  public IUnityContainer RegisterInstance<TInterface>(TInterface instance)
  {
    return this.RegisterInstance(typeof(TInterface), null, instance, new ContainerControlledLifetimeManager());
  }
  public IUnityContainer RegisterInstance<TInterface>(string name, TInterface instance)
  {
    return this.RegisterInstance(typeof(TInterface), name, instance, new ContainerControlledLifetimeManager());
  }
  public IUnityContainer RegisterInstance<TInterface>(TInterface instance, LifetimeManager lifetimeManager)
  {
    return this.RegisterInstance(typeof(TInterface), null, instance, lifetimeManager);
  }
  public IUnityContainer RegisterInstance(Type t, object instance)
  {
    return this.RegisterInstance(t, null, instance, new ContainerControlledLifetimeManager());
  }
  public IUnityContainer RegisterInstance<TInterface>(string name, TInterface instance, LifetimeManager lifetimeManager)
  {
    return this.RegisterInstance(typeof(TInterface), name, instance, lifetimeManager);
  }
  public IUnityContainer RegisterInstance(Type t, object instance, LifetimeManager lifetimeManager)
  {
    return this.RegisterInstance(t, null, instance, lifetimeManager);
  }
  public IUnityContainer RegisterInstance(Type t, string name, object instance)
  {
    return this.RegisterInstance(t, name, instance, new ContainerControlledLifetimeManager());
  }
  //Remaining code removed for brevity
}

all of these methods just delegate to the one method overload left as abstract

public abstract IUnityContainer RegisterInstance(
    Type t, 
    string name, 
    object instance, 
    LifetimeManager lifetime);

The obvious thing to do here is to just make all of these extension methods in the same namespace as the interfaces

public static class IContainerExtensions
{
  public IContainer RegisterInstance<TInterface>(this IContainer container, TInterface instance)
  {
    return container.RegisterInstance(typeof(TInterface), null, instance, new ContainerControlledLifetimeManager());
  }
  public IContainer RegisterInstance<TInterface>(this IContainer container, string name, TInterface instance)
  {
    return container.RegisterInstance(typeof(TInterface), name, instance, new ContainerControlledLifetimeManager());
  }
  public IContainer RegisterInstance<TInterface>(this IContainer container, TInterface instance, LifetimeManager lifetimeManager)
  {
    return container.RegisterInstance(typeof(TInterface), null, instance, lifetimeManager);
  }
  public IContainer RegisterInstance(this IContainer container, Type t, object instance)
  {
    return container.RegisterInstance(t, null, instance, new ContainerControlledLifetimeManager());
  }
  public IContainer RegisterInstance<TInterface>(this IContainer container, string name, TInterface instance, LifetimeManager lifetimeManager)
  {
    return container.RegisterInstance(typeof(TInterface), name, instance, lifetimeManager);
  }
  public IContainer RegisterInstance(this IContainer container, Type t, object instance, LifetimeManager lifetimeManager)
  {
    return container.RegisterInstance(t, null, instance, lifetimeManager);
  }
  public IContainer RegisterInstance(this IContainer container, Type t, string name, object instance)
  {
    return container.RegisterInstance(t, name, instance, new ContainerControlledLifetimeManager());
  }
}

This now reduces our IContainer Interface to just the one method

public interface IContainer
{
  IContainer RegisterInstance(Type t, string name, object instance, LifetimeManager lifetime);
}


One thing to note here is that we have broken the contract because we now return IContainer not IUnityContainer. We will come back to this problem later.
If we then follow suit on the other interfaces we have created, we will have 6 interfaces that look like this:

public interface IContainer
{
  IContainer RegisterType(Type from, Type to, string name, LifetimeManager lifetimeManager, params InjectionMember[] injectionMembers);
  IContainer RegisterInstance(Type t, string name, object instance, LifetimeManager lifetime);
  object Resolve(Type t, string name);
  IEnumerable<object> ResolveAll(Type t);
}
public interface IExtensionContainer
{
  IExtensionContainer AddExtension(UnityContainerExtension extension);
  IExtensionContainer RemoveAllExtensions();
}
public interface ILifecycleContainer
{
  object BuildUp(Type t, object existing, string name);
  void Teardown(object o);
}
public interface INestedContainer
{
  INestedContainer CreateChildContainer();
  INestedContainer Parent { get; }
}
public interface IConfigurableContainer
{
  object Configure(Type configurationInterface);
}
public interface IUnityContainer : IDisposable, IContainer, IExtensionContainer, ILifecycleContainer, INestedContainer, IConfigurableContainer
{}

So now we have some much more managable interfaces to work with. However, we have broken the feature that it had before of returning IUnityContainer from each method. You may ask why would you return the instance when clearly you already have the instance? By doing so you can create a fluent interface. See my other post on Fluent interfaces and DSLs for more information.
Now that we have removed all the noise from the interfaces we actually have a reasonable number of members to work with. This makes me think that maybe we can refactor back to a single interface? Lets have a look:

public interface IUnityContainer : IDisposable
{
  IUnityContainer RegisterType(Type from, Type to, string name, LifetimeManager lifetimeManager, params InjectionMember[] injectionMembers);
  IUnityContainer RegisterInstance(Type t, string name, object instance, LifetimeManager lifetime);
  object Resolve(Type t, string name);
  IEnumerable<object> ResolveAll(Type t);
  IUnityContainer AddExtension(UnityContainerExtension extension);
  IUnityContainer RemoveAllExtensions();
  object BuildUp(Type t, object existing, string name);
  void Teardown(object o);
  IUnityContainer Parent { get; }
  IUnityContainer CreateChildContainer();
  object Configure(Type configurationInterface);
}

Well that is 13 members, which is above my happy limit of 10 and nearly double my ideal limit of 7, however...I think this would be a vast improvement on the silly interface that currently exists with its 42 members.
Just for fun here are the Extension methods that would complete the interface to bring it back to feature complete.

public static class IUnityContainerExtentions
{
  public static IUnityContainer AddNewExtension<TExtension>(this IUnityContainer container) where TExtension : UnityContainerExtension, new()
  {
    return container.AddExtension(Activator.CreateInstance<TExtension>());
  }
  public static T BuildUp<T>(this IUnityContainer container, T existing)
  {
    return (T)container.BuildUp(typeof(T), existing, null);
  }
  public static object BuildUp(this IUnityContainer container, Type t, object existing)
  {
    return container.BuildUp(t, existing, null);
  }
  public static T BuildUp<T>(this IUnityContainer container, T existing, string name)
  {
    return (T)container.BuildUp(typeof(T), existing, name);
  }
  public static TConfigurator Configure<TConfigurator>(this IUnityContainer container) where TConfigurator : IUnityContainerExtensionConfigurator
  {
    return (TConfigurator)container.Configure(typeof(TConfigurator));
  }
  public static IUnityContainer RegisterInstance<TInterface>(this IUnityContainer container, TInterface instance)
  {
    return container.RegisterInstance(typeof(TInterface), null, instance, new ContainerControlledLifetimeManager());
  }
  public static IUnityContainer RegisterInstance<TInterface>(this IUnityContainer container, string name, TInterface instance)
  {
    return container.RegisterInstance(typeof(TInterface), name, instance, new ContainerControlledLifetimeManager());
  }
  public static IUnityContainer RegisterInstance<TInterface>(this IUnityContainer container, TInterface instance, LifetimeManager lifetimeManager)
  {
    return container.RegisterInstance(typeof(TInterface), null, instance, lifetimeManager);
  }
  public static IUnityContainer RegisterInstance(this IUnityContainer container, Type t, object instance)
  {
    return container.RegisterInstance(t, null, instance, new ContainerControlledLifetimeManager());
  }
  public static IUnityContainer RegisterInstance<TInterface>(this IUnityContainer container, string name, TInterface instance, LifetimeManager lifetimeManager)
  {
    return container.RegisterInstance(typeof(TInterface), name, instance, lifetimeManager);
  }
  public static IUnityContainer RegisterInstance(this IUnityContainer container, Type t, object instance, LifetimeManager lifetimeManager)
  {
    return container.RegisterInstance(t, null, instance, lifetimeManager);
  }
  public static IUnityContainer RegisterInstance(this IUnityContainer container, Type t, string name, object instance)
  {
    return container.RegisterInstance(t, name, instance, new ContainerControlledLifetimeManager());
  }
  public static IUnityContainer RegisterType<T>(this IUnityContainer container, params InjectionMember[] injectionMembers)
  {
    return container.RegisterType(typeof(T), null, null, null, injectionMembers);
  }
  public static IUnityContainer RegisterType<TFrom, TTo>(this IUnityContainer container, params InjectionMember[] injectionMembers) where TTo : TFrom
  {
    return container.RegisterType(typeof(TFrom), typeof(TTo), null, null, injectionMembers);
  }
  public static IUnityContainer RegisterType<T>(this IUnityContainer container, LifetimeManager lifetimeManager, params InjectionMember[] injectionMembers)
  {
    return container.RegisterType(typeof(T), null, null, lifetimeManager, injectionMembers);
  }
  public static IUnityContainer RegisterType<TFrom, TTo>(this IUnityContainer container, LifetimeManager lifetimeManager, params InjectionMember[] injectionMembers) where TTo : TFrom
  {
    return container.RegisterType(typeof(TFrom), typeof(TTo), null, lifetimeManager, injectionMembers);
  }
  public static IUnityContainer RegisterType<T>(this IUnityContainer container, string name, params InjectionMember[] injectionMembers)
  {
    return container.RegisterType(typeof(T), null, name, null, injectionMembers);
  }
  public static IUnityContainer RegisterType<TFrom, TTo>(this IUnityContainer container, string name, params InjectionMember[] injectionMembers) where TTo : TFrom
  {
    return container.RegisterType(typeof(TFrom), typeof(TTo), name, null, injectionMembers);
  }
  public static IUnityContainer RegisterType(this IUnityContainer container, Type t, params InjectionMember[] injectionMembers)
  {
    return container.RegisterType(t, null, null, null, injectionMembers);
  }
  public static IUnityContainer RegisterType<T>(this IUnityContainer container, string name, LifetimeManager lifetimeManager, params InjectionMember[] injectionMembers)
  {
    return container.RegisterType(typeof(T), null, name, lifetimeManager, injectionMembers);
  }
  public static IUnityContainer RegisterType<TFrom, TTo>(this IUnityContainer container, string name, LifetimeManager lifetimeManager, params InjectionMember[] injectionMembers) where TTo : TFrom
  {
    return container.RegisterType(typeof(TFrom), typeof(TTo), name, lifetimeManager, injectionMembers);
  }
  public static IUnityContainer RegisterType(this IUnityContainer container, Type t, LifetimeManager lifetimeManager, params InjectionMember[] injectionMembers)
  {
    return container.RegisterType(t, null, null, lifetimeManager, injectionMembers);
  }
  public static IUnityContainer RegisterType(this IUnityContainer container, Type t, string name, params InjectionMember[] injectionMembers)
  {
    return container.RegisterType(t, null, name, null, injectionMembers);
  }
  public static IUnityContainer RegisterType(this IUnityContainer container, Type from, Type to, params InjectionMember[] injectionMembers)
  {
    container.RegisterType(from, to, null, null, injectionMembers);
    return container;
  }
  public static IUnityContainer RegisterType(this IUnityContainer container, Type t, string name, LifetimeManager lifetimeManager, params InjectionMember[] injectionMembers)
  {
    return container.RegisterType(t, null, name, lifetimeManager, injectionMembers);
  }
  public static IUnityContainer RegisterType(this IUnityContainer container, Type from, Type to, LifetimeManager lifetimeManager, params InjectionMember[] injectionMembers)
  {
    return container.RegisterType(from, to, null, lifetimeManager, injectionMembers);
  }
  public static IUnityContainer RegisterType(this IUnityContainer container, Type from, Type to, string name, params InjectionMember[] injectionMembers)
  {
    return container.RegisterType(from, to, name, null, injectionMembers);
  }
  public static T Resolve<T>(this IUnityContainer container)
  {
    return (T)container.Resolve(typeof(T));
  }
  public static T Resolve<T>(this IUnityContainer container, string name)
  {
    return (T)container.Resolve(typeof(T), name);
  }
  public static object Resolve(this IUnityContainer container, Type t)
  {
    return container.Resolve(t, null);
  }
  public static IEnumerable<T> ResolveAll<T>(this IUnityContainer container)
  {
    //return new <ResolveAll>d__0<T>(-2) { <>4__this = this };
    //This implementation requires more effort than I am willing to give (6hours till my holiday!)
  }
}

Bloody hell. Imagine trying to implement that on every class that implemented the interface!

While I know this entire post is academic as we cant change Unity, but I hope that sews some seeds for other developers so that when they design their next interface it wont have silly overloads that just make the consuming developer's job harder than it ought to be.

Monday, January 19, 2009

5 reasons why I love Immutable objects

An old colleague (Jason Langford) first piqued my interest in the "readonly" keyword probably 18months ago. I had read about it in the FDG with regards to exposing arrays from properties and providing setter on Enumerable properties (eg Collections) which is most of the time a silly idea. I then heard about the benefits of Immutable objects in concurrent programming from Joel Pobar during an excellent presentation on the future of Multi-threaded programming. And now I as I complete reading Eric Evan's brilliant book I see that this stuff has been encouraged by him since 2004. So, my 5 reasons I love Immutable objects
  • Reduced cognitive load. Once created that is it, no need to mentally track any changes or side effects.
  • Expressive/Discoverable. Readonly objects are easy to use because there is only one way, Construct --> read. See pit of success
  • Maps to DDD concept of a value type
  • Enabler of side effect free programming
  • .. therefore they are thread safe

Wednesday, December 17, 2008

What's in a name?

A rose by any other name....

Well not in software Romeo. Colin at Abstract.com posted an entry on obvious comments and how they probably indicate rubbish design/naming of methods and variables.

I am just stumbling into this kind of thing now. The client has asked for "Attachments" to be added to an entity in a system I am working on. When they say attachments they just want to upload documents and them to be linked to the entity. Sounds reasonable. So a developer has gone off and created an Attachment class.

I might be being picky here, but to me there is a subtle difference between Attachment, File and say Document or Image. Attachment describes a relationship, File describes an entity representing a file. You may sub class File with Document which might expose a Title, Subject Author properties. You may sub class File with Image and provide Width & Height Properties. But I doubt you would ever have a type of Attachment. If I wanted to add attachments to an entity I could call its void AddAttachment(File attachment) method with my uploaded document, image or simple file. To retrieve them I might use

IEnumerable<File> ListAttachments()
method or maybe just a simple
IEnumerable<File> Attachements
property.

Yeah its picky. Instead of just poking fun at someones design I may try to resurect an old design I had for this space (cheap and nasty DMS), and post it for public mockery.

Wednesday, November 12, 2008

How C# 3.0 helps you with creating DSL

Carrying on with the last post on how Method Chaining can help you create a DSL, I thought I would plagiarise some more content that Ian Cooper shared with us last night at the London DNUG.

Ian discussed the simple example of how in some languages it is very easy/readable to do something as simple as creating a DateTime of "20 minutes ago"

Ruby Code :

20.minutes.ago

C# Code:

DateTime.Now.AddMinutes(-20);

To be fair the C# code is not awful, but is less like a DSL and could be made a touch better. So how does C#3.0 help? Extension methods allow us to extend functionality of another type that we may not have defined. So in this example we can migrate to a Ruby style by implementing 2 extension methods.

public static TimeSpan Minutes(this int numberOfMinutes)
{
    return new TimeSpan(0, numberOfMinutes, 0);
}

public static DateTime Ago(this TimeSpan numberOfMinutes)
{
    return DateTime.Now.Subtract(numberOfMinutes);
}

By creating these extension methods we now give int types a new method Minutes() that returns a TimeSpan. We then extend the TimeSpan type to have an Ago() method that returns a DateTime. Very simple stuff that allows us to write code like this

20.Minutes().Ago();

Others have covered this topic before here

Method Chaining to create your DSL

I just attended a London DNUG hosted by Ian Cooper regarding Internal DSLs in C#3.0. It was a very interesting session where Ian covered some very similar content to JP Boodhoo's series of 5 "Demystifying patterns" on DNRTV.com. Firstly Ian Covered simply what a DSL is and how there can be DSL internal to .NET. His examples were RhinoMock (and nMock), LINQ and implementations of a fluent API using strategy patterns and method chaining.

While I have seen people use method chaining before primarily in demos or when I have been using RhinoMocks but I have never heard any guidance on how to construct them. As a quick intro to method chaining and why they constitute a DSL here is an example similar to Ian's.

In this example we create a Meeting type using a MeetingBuilder.

var meeting = new MeetingBuilder()
    .On("C# Internal DSLs")
    .By("Ian Cooper")
    .And("Someone else")
    .At( new Address()
        {
            Street1 = "Skills Matter"
            Street2 = "1 something lane"
            PostCode = "SE1ABC"
        })
    .From(new DateTime(2008, 11, 11, 18, 30))
    .Until(new DateTime(2008, 11, 11, 20, 00))
    .Create();
The general Idea here is that we create something that looks more like English language than standard C# code.

So having shown a simple example of Method chaining, I think it is fair to say that it is quite readable and that non technical people (eg Mum) could probably figure out what I am doing here

Ian Copper and somebody else is presenting "C# Internal DSLs" at Skills Matter on 18:30 11th Nov.

If we analyse the code, first thing I would like to mention is that Ian recommends that all methods from a chaining builder (in this case MeetingBuilder) should return this except the Create() method that returns the final object. Now having considered this, that means that we can deduce that MeetingBuilder has a method On(string). Now considering that On(string) is a method on a Builder it should also return the Builder. Cool. By that rational we can also deduce that By(string), And(string), At(Address), From(DateTime), To(DateTime) and Create() are all methods on MeetingBuilder.

Well that is not so interesting until we consider that if we want to create a really fluent API. For the API to be fluent it should not only be readable, we should provide guidance for consuming it too. Referring back to the example we can see the we probably have mandatory method calls and optional methods. In this case only the And(string) method is optional, all of the others should be mandatory. So how can we drive the consumer/developer to know how to use the API if all methods return this?
The answer : Interfaces.

By setting the return types of the methods to interfaces, we can constrain what the next method can do. We still return this, which then tells us we need to implement a bunch of interfaces. The first method this example requires is On(string) so we need an interface like:

interface IMeetingSubjectBuilder
{
    object On(string);
}

but we cant just return object, we need to return an interface that guides the developer to provide the name of the presenter so we expand our interface definitions

interface IMeetingSubjectBuilder
{
   IMeetingPresenterBuilder On(string subject);
}
interface IMeetingPresenterBuilder
{
    IMeetingPresenterOrAddressBuilder By(string presenter);
}
interface IMeetingPresenterOrAddressBuilder 
{
    IMeetingPresenterOrAddressBuilder And(string otherPresenter);
    IMeetingFromTimeBuilder At(Address address);
}

In the above step we have actually done a few things. Firstly we have swapped out the rubbish return type of object for the IMeetingPresenterBuilder. This will then guide our developers to use the methods on that interface. Next we declare that new interface has the By(string) method. This method returns a third interface. The third interface provides two methods. The first method is the And(string) method that allows us to provide additional presenters. Note that its return type is the interface that defines it, which allows a us to recursively call it to add multiple presenters. The second method provides a way to continue providing Address data and eventually other data.

To jump ahead quickly, here is what the final set of interfaces might look like

interface IMeetingSubjectBuilder
{
   IMeetingPresenterBuilder On(string subject);
}
interface IMeetingPresenterBuilder
{
    IMeetingPresenterOrAddressBuilder By(string presenter);
}
interface IMeetingPresenterOrAddressBuilder 
{
    IMeetingPresenterOrAddressBuilder And(string otherPresenter);
    IMeetingFromTimeBuilder At(Address address);
}
interface IMeetingFromTimeBuilder
{
    IMeetingToTimeBuilder From(DateTime startTime);
}
interface IMeetingToTimeBuilder
{
    IMeetingCreator Until(DateTime endTime);
}
interface IMeetingCreator
{
    Meeting Create();
}

Well this is good progress, so all we have to do now is declare a class that implements these interfaces.

class MeetingBuilder : IMeetingSubjectBuilder, IMeetingPresenterBuilder, IMeetingPresenterOrAddressBuilder, IMeetingFromTimeBuilder, IMeetingToTimeBuilder, IMeetingCreator
{
    public IMeetingPresenterBuilder On(string subject){...}
    public IMeetingPresenterOrAddressBuilder By(string presenter){...}
    public IMeetingPresenterOrAddressBuilder And(string otherPresenter){...}
    public IMeetingFromTimeBuilder At(Address address){...}
    public IMeetingToTimeBuilder From(DateTime startTime){...}
    public IMeetingCreator Until(DateTime endTime){...}
    public Meeting Create() {...}
}

One final problem here is that if we were to use this as per the first example we would find that we could call any of the methods straight from the constructor which could confuse the developer. To better guide the developer we can simply implement all of the interface explicitly except for IMeetingSubjectBuilder.

class MeetingBuilder : IMeetingSubjectBuilder, 
    IMeetingPresenterBuilder, 
    IMeetingPresenterOrAddressBuilder, 
    IMeetingFromTimeBuilder, 
    IMeetingToTimeBuilder, 
    IMeetingCreator
{
    public IMeetingPresenterBuilder On(string subject){...}
    IMeetingPresenterOrAddressBuilder IMeetingPresenterBuilder.By(string presenter){...}
    IMeetingPresenterOrAddressBuilder IMeetingPresenterOrAddressBuilder.And(string otherPresenter){...}
    IMeetingFromTimeBuilder IMeetingPresenterOrAddressBuilder.At(Address address){...}
    IMeetingToTimeBuilder IMeetingFromTimeBuilder.From(DateTime startTime){...}
    IMeetingCreator IMeetingToTimeBuilder.Until(DateTime endTime){...}
    Meeting IMeetingCreator.Create(){...}
}

Now when we create an instance of MeetingBuilder we are guided as to which methods are valid in which order and have a nice fluent API. From the constructor we have the On(string) method available, then from there we have the By(string) and so on.

Creating a Fluent API (and therefore an internal DSL) does require more work and some extra effort at design time but it does make for very nice coding experience for the end developer. For more information see what the godfather has to say here : http://martinfowler.com/dslwip/MethodChaining.html

Wednesday, November 5, 2008

Fail fast

Big Col nails the philosophy of fail fast in his recent blog posts. His first post covers this philosophy at a system level and his second post discusses what you can do in your C#/VB.NET/Java code until fancy Eiffel constructs like spec# make there way in to our languages.

Friday, October 31, 2008

Framework Design Guidelines v2

Brad and Krys are just about to release v2 of their great book Framework Design Guidelines. Here is a link to their recent "pre-release" talk at PDC. I am a big fan of this subject area and find it relevant to all levels of developers. So if you havn't read the original book try to get this new version, or at least watch the video ;-)

Wednesday, August 20, 2008

.Net user group videos – Perth (Perth DNUG)

For those that attend the Perth .Net User Group meetings, you may have noticed the video camera recently. I have finally got all of my toys working together to get the files off the camera and on to the web.

In order of appearance:

Community Launch topics – July 3rd

Dave Gardner presenting Web development in Visual Studio 2008: MP4 Video (140MB ~20min)

Mike Minutillo presenting CSharp 3.0: MP4 Video (154MB ~22min)

Alistair Waddell LINQ and LINQ-to-SQL Features: MP4 Video (151MB ~22min)

Mitch Denny presenting Testable Workflows : MP4 Video (109MB ~15min)

Bill Chestnut Hands On WCF – Jul 10

Bill Chestnut presenting Hands on WCF : MP4 Video (400MB ~57min)

Dwayne Read Agile .NET – Aug 7

Dwayne Read from Strategic Systems presents a discussion on Agile practices in a .Net environment.

Apologies for the video. The final 10 minutes of the video were cut out. While they were key to the presentation I still thought there was value in releasing the video anyway.

MP4 Video(388MB ~55min)