Register Login

 

Welcome to the Coach Factor blog. Here you will find all of our ideas on software development. Subscribe at  http://blog.nventive.net.

# Wednesday, March 12, 2008

Part 1 presented a recap of extension methods. If you're not familiar with the concept, you should check it first.

Cohesion

The main concern with extension methods is that they aren't for everything; they have to be cohesive with the type being extended.

Let's say we add another extension method to the string class from the previous post:

  public static class StringExtensions

  {

    public static bool IsValidEmailAddress(this string instance)

    {

      if (instance.HasValue())

      {

        Regex expression = new Regex(

        @"[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'

                *+/=?^_`{|}~-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z             

                0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?");

 

        return expression.IsMatch(instance);

      }

      else

      {

        return false;

      }

    }

  }

Does this really make sense? Definitely not!

A string is not intended to contain "exclusively" email addresses; so you end up polluting your string class with domain-specific extensions.

  public class StringExtensionsFixture

  {

    [Fact]

    public void ConnectionString_Polluted()

    {

      string connectionString = "Data Source=myServerAddress;Initial Catalog=myDataBase;Integrated Security=SSPI;";

      Assert.False(connectionString.IsValidEmailAddress()); //Doesn't make sense!

    }

  }

Facade

Extension Methods should really be used to facade and simplify usage of existing scenarios without adding extra coupling on external concepts:

  public static class TypeExtensions

  {

    public static bool Is<T>(this Type type)

    {

      return typeof(T).IsAssignableFrom(type);

    }

  }

 

  public static class TypeExtensionsFixture

  {

    [Fact]

    public void Is()

    {

      // Without the extension, logic relies on the understanding of the obscure method "IsAssignableFrom".

      Assert.True(typeof(IComparable).IsAssignableFrom(typeof(int)));

 

      // With the extension, the developer leverages existing knowledge of the "is" operator

      Assert.True(typeof(int).Is<IComparable>());

    }

  }

One imporant thing to notice here is the usage of a "generic" extension method. We'll delve into more details about generic extension methods in a subsequent post.

However, some cross-cutting concerns such as Serialization, Conversion, Equality benefit largely from being published as extension methods instead of remaining in their own "helper" classes. The main reason for this is discoverability. Some people will argue that since the extension method isn't part of the extended type per se, it lowers discoverability.  "Helper" methods aren't any more discoverable.

Extension Point

Let's say we want to add the serialization "functionality" to any object, we could use extension methods and write something like:

  public static class SerializationExtension

  {

    public static void ToXml<T>(this T instance, string fileName)

    {

      XmlSerializer serializer = new XmlSerializer(typeof(T));

 

      FileStream stream = File.OpenWrite(fileName);

 

      using (stream)

      {

        serializer.Serialize(stream, instance);

      }

    }

 

    public static void ToBinary<T>(this T instance, string fileName)

    {

      BinaryFormatter formatter = new BinaryFormatter();

 

      FileStream stream = File.OpenWrite(fileName);

 

      using (stream)

      {

        formatter.Serialize(stream, instance);

      }

    }

  }

SerializationMessy

What's the problem here? We started polluting the "Person" type with non-related concerns such as Xml and Binary serialization. Just imagine one moment all the additional methods that could suddenly appear and pollute the Person object. It would lead to "Extension Method Hell".

One remedy is to try to group those methods into "Extension Points", grouping them by how related the concern is.

Introducing: the Extension Point object:

  public class SerializationExtensionPoint<T>

  {

    public T Value { get; set; }

  }

 

The goal of the extension point is to wrap an instance with a "typed scope", allowing the extension methods to be programmed against the extension point instead of the instance itself.

  public static class SerializationExtension

  {

    public static void ToXml<T>(this T instance, string fileName)

    {

      XmlSerializer serializer = new XmlSerializer(typeof(T));

 

      FileStream stream = File.OpenWrite(fileName);

 

      using (stream)

      {

        serializer.Serialize(stream, instance);

      }

    }

 

    public static void ToBinary<T>(this T instance, string fileName)

    {

      BinaryFormatter formatter = new BinaryFormatter();

 

      FileStream stream = File.OpenWrite(fileName);

 

      using (stream)

      {

        formatter.Serialize(stream, instance);

      }

    }

  }

We've added the Serialization() extension method that provides the typed scope. Other scopes could group non-functional extensions like Equality, Conversion and Comparison.

Serialization

In the image above, we can clearly see that the interface is a lot more cohesive and has only been polluted with a Serialization aspect.

The complete code would look something like:

  public class SerializationExtensionFixture

  {

    [Fact]

    public void ToXml()

    {

      Person person = new Person { FirstName = "John", LastName = "Doe" };

      person.Serialization().ToXml("john.xml");

    }

  }

 

In the next post, we'll try to explore in more details how we can benefit from generics in extension methods.

Wednesday, March 12, 2008 1:55:15 AM (Eastern Standard Time, UTC-05:00)  #    Comments [0] -
.net | .net - Extension Methods

Extension Methods is a cool new feature of .NET 3.5. It's syntactic sugar invented mainly for LINQ and allow the developer to get rid of most of the static "helper" methods.

If you haven't delved into them, here's a quick recap on how they're implemented using C# 3.0:

  public static class StringExtensions

  {

    public static bool HasValue(this string instance)

    {

      return !string.IsNullOrEmpty(instance);

    }

  }

Just remember there are three steps to define an extension method:

    • static class

    • static method

    • this modifier

      Once that done, you can use the method like any other instance method:

        public class StringExtensionsFixture

        {

          [Fact]

          public void HasValue_Null()

          {

            string text = null;

       

            Assert.False(text.HasValue());

       

            // What the compiler is calling behind the scenes

            Assert.False(StringExtensions.HasValue(text));

          }

      
      

      However, extension methods are different from regular instance methods as:

      • They support null references

      string text = null;

       

      // Will not throw a NullReferenceException

      Assert.False(text.HasValue());

      • They allow you to extend sealed classes by adding methods

      public sealed class String { ... }

      In an upcoming post, we'll show you how design considerations are really important when extending existing types.

      Wednesday, March 12, 2008 1:51:48 AM (Eastern Standard Time, UTC-05:00)  #    Comments [0] -
      .net | .net - Extension Methods
      # Tuesday, March 11, 2008

      nVentive will be presenting at the Ottawa Code Camp on April 5th. It's a free day, and a great opportunity to see what's happening in software development.

      Tuesday, March 11, 2008 8:32:08 PM (Eastern Standard Time, UTC-05:00)  #    Comments [0] -
      Announcement
      # Sunday, March 02, 2008

      nVentive will be participating at the Heros Happen Here event in Quebec city on April 17th. We will be answering any questions you might have on the great new products launched by Microsoft. nVentive already has a lot of experience with these new products, and we hope to share some tips with all of you.

      Sunday, March 02, 2008 8:31:36 PM (Eastern Standard Time, UTC-05:00)  #    Comments [0] -
      Announcement

      nVentive will be present at DevTeach Toronto during the week of May 12th to May 16th. We will be giving conferences on Enterprise Library, hopefully 4.0 if it's out by then. Find us hanging in the architecure, agile and developer tracks, and don't hesitate to throw a few questions our way if you cross us.

      Sunday, March 02, 2008 8:30:54 PM (Eastern Standard Time, UTC-05:00)  #    Comments [0] -
      Announcement

      On March 3, 2008, the nVentive team will be presenting at the GUVSM, Montreal. During this conference we will talk about WCF, the newest communication technology for .NET created by Microsoft. Come and join us for this even. This is a great opportunity to learn what this technology is all about, how to use it and to see some advanced tricks.

      Sunday, March 02, 2008 8:30:09 PM (Eastern Standard Time, UTC-05:00)  #    Comments [0] -

      Search
      Archive
      <March 2008>
      SunMonTueWedThuFriSat
      2425262728291
      2345678
      9101112131415
      16171819202122
      23242526272829
      303112345
      Statistics
      Total Posts: 47
      This Year: 0
      This Month: 0
      This Week: 0
      Comments: 2
      Sign In