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, November 19, 2008

For some of the work that Erik has done with Microsoft Patterns and Practices group, he has won a PnP Champion award. Find out more details at msdn.

 

Wednesday, November 19, 2008 10:54:48 PM (Eastern Standard Time, UTC-05:00)  #    Comments [0] -
.net | Announcement | Architecture
# Tuesday, October 28, 2008

We are happy to announce (or repeat) that Enterprise Library 4.1 and Unity 1.2 from Microsoft PnP group is out. Why are we so happy, well nVentive collaborated with Microsoft on this project.

This service release is a minor one, but brings one major new functionality : Interception from Unity. If you are using Unity as your IOC, i strongly urge you to upgrade to this new version and find that:

  1. The container can resolve itself :)
  2. AOP programming is one step closer. You can reuse the matching rules and call handlers from PIAB, or invent your own.

We'll be blogging about this new release very soon, with code examples to get you going.

As always, you can find these on CodePlex (http://www.codeplex.com/unity or http://www.codeplex.com/entlib) or the msdn landing pages (http://msdn.microsoft.com/en-us/library/aa138002.aspx).

Tuesday, October 28, 2008 12:21:57 PM (Eastern Standard Time, UTC-05:00)  #    Comments [0] -
.net
# Thursday, September 25, 2008

nVentive will be presenting it's "Top 10 Umbrellas" talk at the Ottawa.NET Community on Thursday, November 5th. Come and hear us talk about Umbrella and how the ideas within can save you development time.

Thursday, September 25, 2008 12:02:22 PM (Eastern Standard Time, UTC-05:00)  #    Comments [0] -
.net | Announcement | Umbrella
# Monday, September 22, 2008

One of the nice things of the latest versions of .net, is the ObservableCollection<T>. This class implements the new INotifyCollectionChanged interface (similar to INotifyPropertyChanged that we all know). Here is a small code example:

    1         [TestMethod]

    2         public void ObservingAReadOnlyObservableCollectionSucceeds()

    3         {

    4             //setup original collection with some initial content;

    5             ObservableCollection<string> strings = new ObservableCollection<string>();

    6             strings.Add("string1");

    7             strings.Add("string2");

    8 

    9             //setup readonly collection

   10             ReadOnlyObservableCollection<string> readOnlyStrings = new ReadOnlyObservableCollection<string>(strings);

   11             int addedElementsWhileObservingReadOnlyCollection = 0;

   12 

   13             //setup observer

   14             (readOnlyStrings as INotifyCollectionChanged).CollectionChanged += delegate(object sender, NotifyCollectionChangedEventArgs e)

   15                     {

   16                         if (e.Action == NotifyCollectionChangedAction.Add)

   17                         {

   18                             addedElementsWhileObservingReadOnlyCollection += e.NewItems.Count;

   19                         }

   20                     };

   21 

   22             //add one item, addign should be observed

   23             strings.Add("addedString");

   24 

   25             //assert

   26             Assert.AreEqual(3, readOnlyStrings.Count);

   27             Assert.AreEqual(1, addedElementsWhileObservingReadOnlyCollection);

   28         }

Notice the usage of ReadOnlyObservableCollection<T>, which can be used when you don't want someone to alter the contents of a collection.

These are the problems we see with all this new goodness:

  1. These types reside in the WindowsBase.DLL assembly with weird innapropriate namespaces.
  2. ReadOnlyObservableCollection<T> and ObservableCollection<T> implement INotifyPropertyChanged explicitly, meaning you have to cast to INotifyPropertyChanged to be able to use notifications.
Monday, September 22, 2008 5:48:40 PM (Eastern Standard Time, UTC-05:00)  #    Comments [0] -
.net
# Friday, September 19, 2008

nVentive will be sponsoring the Montreal .NET community, it's our way of promoting this great group. They offer many meetings per month where great subjects are featured. It's one of our ways of offering coaching and guidance to the Montreal community.

Friday, September 19, 2008 1:22:06 PM (Eastern Standard Time, UTC-05:00)  #    Comments [0] -
.net | Announcement
# Tuesday, September 09, 2008

nVentive will be presenting some cool material at the new Microsoft TechDays conference in Montreal on November 6th and 7th. Be sure to be there as the subjects are the latest and will surely help you increae your team's software developement velocity.

Tuesday, September 09, 2008 3:51:52 PM (Eastern Standard Time, UTC-05:00)  #    Comments [0] -
.net | Announcement
# Wednesday, September 03, 2008

Well, such a nice tool was bound to be aquired by a company. Reflector has been acquired by Red-Gate software. You can find Reflector at http://reflector.red-gate.com.

Speaking of Reflector though, did you know there were over 30 plugins available ?

On the subject of plugins, the excellent TestDriven.net addin for Visual Studio will add a few context menu item for running your tests, but will also add one that allows you to jump back to Reflector. Isn't it nice when all these tools play nice together ?

Wednesday, September 03, 2008 2:27:09 AM (Eastern Standard Time, UTC-05:00)  #    Comments [0] -
.net
# Wednesday, August 27, 2008

Grigori, from Microsoft's PnP announced last week that there will be a new version of Enterprise Library coming out. It's a smaller version, when you look at the features coming out, but it's a welcome one as a few bugs will be fixed.

The first intermediate drop (before the final release) of the source code is already there, so feel free to grab it and see how the new features can help you right now at http://www.codeplex.com/entlib.

Wednesday, August 27, 2008 1:39:53 AM (Eastern Standard Time, UTC-05:00)  #    Comments [0] -
.net
# Tuesday, August 26, 2008

Visual Studio 2008 SP1 has been out now for a few days, and we must say we like it. It brings a ton of enhancements to the IDE and to the .NET framework; and these are the things that hit us the most:

  • Better WPF Designers - there were a few bugs in the original ones and I'm glad to say they are fixed.
  • Entity Framework - well we were waiting for this one for a long time. We can now start to build OR architectures with design tools provided by Microsoft. You might hear in the community that version 1 is not perfect, and they are right. Version 2 is coming out eventually and they are already discussing ideas for people to judge, see this rss feed. The team also has a wiki to gather community ideas.
  • ADO.NET Data Services - AKA Astoria, this project exposes a Data Service in a RESTful way. It can basically expose anything that is IQueryable and offers hooks to manage security, transactions, updates, etc... There is a small tool that will allow you to recreate the object model on the client side and get away from using the URL mecanism to query the service. This new service will yield a few new nice architectures we am certain.
  • ASP.NET Dynamic Data - This technology will allow you to rapidly generate an interface from metadata attached to a business object. It's basically a scaffolding technique in order to rapidly generate data driven applications.

We suggest you install this service pack as soon as possible and use it with your forth coming developments. It is rare that a service pack brings so much new technology to the table and they are all welcome.

 

Tuesday, August 26, 2008 1:33:22 AM (Eastern Standard Time, UTC-05:00)  #    Comments [0] -
.net
# Monday, August 25, 2008

The Montreal .NET Community (formelly the GUVSM) has redone itself.

There is a new name and a new website in order to reflect the common interests that the community has in .net related technologies. There will be special interests groups for .Net, Team SystemSql and architecture. What's new though is that Francois and I will be pushing a new concept in the .net group called @Lunch.

@Lunch is basically an open session, once a month, where a subject will examined in a more informal way. It is modeled on the way Alt.NET and opens spaces work and will surely provoke a few interesting discussions. One of the things we will promote is to determine the subject of the next meeting, during the last few minutes of the meeting occuring. What an "Agile" way of learning what's most important. The first @Lunch is scheduled for September 24th and will be moderated by Francois, speaking on extension methods.

I suggest you visit the calendar, and find which sessions interest you the most. You can even subscribe to the calendar through a RSS feed; what a nice touch !

The last thing for this post is an upcoming Umbrella talk; we will be presenting our session called "Top 10 Umbrellas" at the .Net group of the Montreal .Net Community on October 20th. If you're interested in what it is, or how it can help you, we suggest you come by and listen what we have to say.

Monday, August 25, 2008 2:01:02 AM (Eastern Standard Time, UTC-05:00)  #    Comments [0] -
.net | Announcement | Umbrella
# Thursday, May 22, 2008

At DevTeach and the PnP Summit, there were talks on how to use instrumentation within your applications and use it to monitor the health of it throughout it's lifecycle.

At one of our past contracts, we had a problem where our users were not taking the time to test the system correctly. We then resorted to reuse the instrumentation module to track how often the individual functions of the application were used.

At first, it was only about helping them focus on the tests, or rather where they had not tested. But after a few months, it all changed; it actually became a measure of how useful the software was and what parts were being adopted.

It's motivated two things :

  1. When comes a time to prioritize backlog items, we can use these metrics to make sure we do things that are of the highest value for the customer, in parts of the system that we know have high traffic.
  2. Every time we add something to the system, we have metrics that can help us remove something else from the system. This allows the system to constantly stay the same relative size and not carry any "dead weight" into the future.

I'm not sure if Usage Coverage is a good term for these ideas, but for sure, I will be using them in future projects also.

Thursday, May 22, 2008 2:00:05 AM (Eastern Standard Time, UTC-05:00)  #    Comments [0] -
.net
# Tuesday, May 20, 2008

For all those of you who asked about our session material, it is now available for download.

You'll have to login to your devteach account in order to be able to download the material. If the link doesn't work, go directly to the Schedule page, find our AOP + Unity session and you should be able to click on the Material link.

The .zip file contains both the material for the Validation + Security session and the AOP + Unity session.

Tuesday, May 20, 2008 2:02:40 AM (Eastern Standard Time, UTC-05:00)  #    Comments [0] -
.net
# Saturday, May 17, 2008

For those of you who were at DevTeach Toronto and listened us talk about Enterprise Library 4.0 new features, we promised 4.0 was on the way. Well, it's officially released! You can get more information on Grigori's blog

Make sure to also look at what's new in the Unity 1.1 refresh.

Saturday, May 17, 2008 2:03:14 AM (Eastern Standard Time, UTC-05:00)  #    Comments [0] -
.net
# Monday, May 12, 2008

Hopefully, after reading Part 1, Part 2, Part 3, Part 4 and Part 5, you should've become an Extension Method Master.

But there's more. There are other elements that can be simplified by using extension methods and that is, limiting usage of reflection.

Given something like:

public interface IServiceLocator

{

  T Resolve();

}

 

It is important to notice that the generic method Resolve has a type parameter for the sole purpose of providing the type to resolve. There are NO constraints.

One might use the service locator as follows:

public ILogger GetLogger()

{

  ILogger logger = serviceLocator.Resolve<ILogger>();

 

  return logger;

}

But what if the type to resolve is only known at runtime? You'll have to fallback on reflection:

public static class ServiceLocatorExtensions

{

  public static object Resolve(this IServiceLocator locator, Type type)

  {

    MethodInfo resolveMethodInfo = typeof(IServiceLocator).GetMethod("Resolve");

    resolveMethodInfo = resolveMethodInfo.MakeGenericMethod(type);

 

    return resolveMethodInfo.Invoke(serviceLocator, null);

  }

}

This approach can have terrible performance, especially since there is no reflection cache.

A far better approach is to define your IServiceLocator interface as a non-generic interface and provide strongly-typed extension methods:

public interface IServiceLocator

{

  object Resolve(Type type);

}

and

public static class ServiceLocatorExtensions

{

  public static T Resolve(this IServiceLocator locator)

  {

    return (T)locator.Resolve(typeof(T));

  }

}

 

Thoughts?

powered by metaPost

Monday, May 12, 2008 2:04:40 AM (Eastern Standard Time, UTC-05:00)  #    Comments [0] -
.net | .net - Extension Methods
# Wednesday, April 30, 2008

Yesterday I was helping somebody with a small WCF application and one of the tools I proposed was a plugin visualizer for Visual Studio called WCF Visualizers. It's available freely on CodePlex and will allow you to see different parts of WCF (messages, endpoints, channels...) while you are debugging. Go and check it out, as there are some great images on the project page. The next time I give a WCF presentation with Francois at different user groups, I will also take the time demo this tool.

Wednesday, April 30, 2008 2:05:22 AM (Eastern Standard Time, UTC-05:00)  #    Comments [0] -
.net
# Monday, April 21, 2008

nVentive was present in Quebec city at HEROES happen {here}, Microsoft's launch for Visual Studio.Net 2008, SQL Server 2008 and Windows Server 2008.

François and I were experts there on the developer side of things, and the one thing we got asked the most, were questions on LINQ.

Everybody knows that LINQ is the hot new way to query objects in C# using a syntax similar to SQL. It depends on 2 tricks, Extension Methods and Lanbda Expressions.

This is a small sample.

public class Blog

{

   public string Title { get; set; }

}

class Program

{

   static void Main(string[] args)

   {

      IList<Blog> blogs = new List<Blog>();

      blogs.Add(new Blog { Title = "3 cheese lasagna" });

      blogs.Add(new Blog { Title = "Blue cheese alfredo sauce" });

      blogs.Add(new Blog { Title = "Macaroni and cheese" });

      blogs.Add(new Blog { Title = "Angel cake" });

 

      var blogsWithCheese = from blog in blogs

            where blog.Title.ToLower().Contains("cheese")

            select blog;

      //blogsWithCheese contains 3 elements.

   }

}

You can query something that is IEnumerable with LINQ to Objects, or a database itself using LINQ to SQL. If XML is your thing, there is a LINQ to XML variant and let's not forget that there is adapter to query Ado.Net DataSets. If you've heard of Entity Framework, LINQ will also work there to abstract it's object SQL language.

Now there's still more, if you have a source that you'd like to query with LINQ, it's just a matter of implementing IQueryProvider and IQueryable.

There are 2 tools I recommend you use in your adventures with LINQ:

  1. LINQPad is a interactive LINQ learning tool. Check it out, you'll never go back into Query Analyzer after that.
  2. Visual LINQ Query Builder is a plugin for Visual Studio 2008 that will help you develop your queries with a designer, now that's practical.

Monday, April 21, 2008 8:33:18 PM (Eastern Standard Time, UTC-05:00)  #    Comments [0] -
.net | Announcement
# Saturday, March 29, 2008

We've covered a lot so far with Part 1, Part 2, Part 3 and Part 4 of this adventure with extension methods.

Looking back at it, there are some nifty features and side effects that might have been overlooked.

With the magic of generic methods and compiler type inference, we are able to get a pretty discoverable and predictable api.

Let's look at the test first:

  [Fact]

  public void GetProperty()

  {

    DateTime now = DateTime.Now;

 

    Assert.Equal(now.Day, now.Reflection().GetProperty("Day"));

  }

What's in there? Well first we see that there is a Reflection() extension point, and this typed extension point has a GetProperty method. This makes it really EASY to figure out what can be done by reflection.

What should the code look like?

Let's start by the extension point class that will scope all available reflection methods:

  public class ReflectionExtensionPoint

  {

    public T Instance { get; set; }

  }

The ReflectionExtensionPoint class is generic so it can hold the type for which we want to use reflection. So we don't have to instantiate it manually all the time, we can create an extension method that will create such an instance

  public static class ReflectionExtension

  {

    public static ReflectionExtensionPoint Reflection(this T instance)

    {

      return new ReflectionExtensionPoint { Instance = instance };

    }

  }

Here lies all the magic. Since the method is generic and there are no constraints define, we can use the Reflection extension method on anything. Furthermore, there is no need to specify the generic type argument as it is automatically inferred by the compiler

This allows for a pretty compact syntax as shown here:

  [Fact]

  public void ReflectionExtensionPoint()

  {

    DateTime now = DateTime.Now;

 

    ReflectionExtensionPoint<DateTime> extensionPoint = now.Reflection();

 

    Assert.NotNull(extensionPoint);

    Assert.Equal(now, extensionPoint.Instance);

  }

Now that we have an extension point almost for free that represents a clear and very predictable subset of functionality, we can extend-the-extension-point to add additional behaviors.

  public static class ReflectionExtension

  {

    public static ReflectionExtensionPoint Reflection(this T instance)

    {

      return new ReflectionExtensionPoint { Instance = instance };

    }

 

    public static void SetProperty(

      this ReflectionExtensionPoint extensionPoint,

      string name,

      object value)

    {

      PropertyInfo propertyInfo = typeof(T).GetProperty(name);

      propertyInfo.SetValue(extensionPoint.Instance, value, null);

    }

 

    public static object GetProperty(

      this ReflectionExtensionPoint extensionPoint,

      string name)

    {

      PropertyInfo propertyInfo = typeof(T).GetProperty(name);

      return propertyInfo.GetValue(extensionPoint.Instance, null);

    }

  }

Of course, extending the generic ReflectionExtensionPoint class, we need to make our extension methods generic as well so that we can propagate the extended type.

By now, unit tests should turn green, and we should be looking for next bits of business value to provide.

powered by metaPost

Saturday, March 29, 2008 1:59:11 AM (Eastern Standard Time, UTC-05:00)  #    Comments [0] -
.net | .net - Extension Methods
# Friday, March 28, 2008

If you haven't read Part 1, Part 2 and Part 3 of this serie, go ahead, we'll wait right here.

In the previous post, we suggested that you can move instance methods that represent overloads to static extension methods.

It's been known for a while that static methods don't do well. They infer with most OO principles and are barely testable. Some will even define those as evil.

Selfishness

When you look at the definition of evil, it is used to indicate acts that are selfish.

Static Methods are selfish in the sense that they keep implementation details for themselves. They take control and keep it. They won't allow you to replace them with a mock version for test purposes. They won't allow their behaviour to be modified without digging into the inner guts and recompiling. They can't be decorated, they can't be proxied, they're selfish.

But can't we have both? The ease and greatness of extension methods without the selfishness and lack of testability of static methods?

Well yes you can... Sort of...

Let's start by looking at an extension method we previously developed:

public static class TypeExtensions

{

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

  {

    return typeof(T).IsAssignableFrom(type);

  }

}

 

It contains almost no code but still, it can't be mocked nor replaced.

Make everything an instance again

In order to replace the implementation of this method with another one, we simply need to

1-Extract this method into an interface

public interface ITypeExtensions

{

  bool Is<T>(Type type);

}

2- Provide a default implementation.

public class DefaultTypeExtensions : ITypeExtensions

{

  public bool Is<T>(Type type)

  {

    return typeof(T).IsAssignableFrom(type);

  }

}

3- Make sure the extension method delegates to the instance method

public static class TypeExtensions

{

  public static ITypeExtensions Extensions = new DefaultTypeExtensions();

 

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

  {

      return Extensions.Is<T>(type);

  }

}

Compromise

On the sunny side, we are now able to completely test our extension method implementation. It can also be mocked as we've extracted an interface. It can be replaced or decorated with a Thread-safe version.

On the dark side, you need to set your mock instance to the public static Extensions field in order for existing code to call the mock. It is sort of an indirect dependency.

Friday, March 28, 2008 1:57:28 AM (Eastern Standard Time, UTC-05:00)  #    Comments [0] -
.net | .net - Extension Methods

Part 1 and Part 2 of this serie presented the basics and design guidelines for developing great extension methods.

Today, we'll try to show how extension methods can be a great tool to lessen the burden of implementing any given interface.

As an example, let's take a look at Unity for a moment.

IUnityContainer is the main interface of Unity. It acts both as a registry of registered type mappings between an abstract type and a concrete type; and as a Service Locator (Dependency Lookup).

What we're used to

Here's a snippet of the RegisterType method with its different overloads:

 public interface IUnityContainer

{

    //...

    IUnityContainer RegisterType()

      where TTo : TFrom;

    IUnityContainer RegisterType(LifetimeManager lifetimeManager)

      where TTo : TFrom;

    IUnityContainer RegisterType(LifetimeManager lifetimeManager);

    IUnityContainer RegisterType(string name)

      where TTo : TFrom;

    IUnityContainer RegisterType(string name, LifetimeManager lifetimeManager)

      where TTo : TFrom;

    IUnityContainer RegisterType(string name, LifetimeManager lifetimeManager);

    IUnityContainer RegisterType(Type t, LifetimeManager lifetimeManager);

    IUnityContainer RegisterType(Type from, Type to);

    IUnityContainer RegisterType(Type t, string name, LifetimeManager lifetimeManager);

    IUnityContainer RegisterType(Type from, Type to, LifetimeManager lifetimeManager);

    IUnityContainer RegisterType(Type from, Type to, string name);

    IUnityContainer RegisterType(Type from, Type to,

      string name, LifetimeManager lifetimeManager);

}

12 different overloads!!! In total, there are 39 different methods on this interface.

Let's focus on the RegisterType method for a sec. What are the main differences between those overloads?

First and foremost, there's the Generic-strongly-typed version and the loosely-typed version. Then there's the name parameter that allows you to register the same type multiple times with different names. Then there's whether or now you want to specify a lifetimeManager.

If we were to implement that interface and all those RegisterType methods, what would happen? How would we do it? Well, we'd probably chain them all to a single one; the same we do it with chained constructors, right? Which one? The more specific one? Definitely:

 IUnityContainer RegisterType(Type from, Type to, string name, LifetimeManager lifetimeManager);

This is the core method. The one that rules them all. All other overloads are only there to ease usage; at the cost of putting a large burden on the developer. If we want to write an IUnityContainer decorator, we'd have 39 methods to implement... again... and out of those 39 methods, only 3 or 4 would have any valuable logic...

Interfaces on a diet

What if we slim down those interfaces. Let's pretend for one moment that we have a great job at Microsoft, working for the p&p team; and most of all, we get to design Unity! Woohoo!

Since we've been reading the Coach Factor (or are about to), we decide to slim down those pesky interfaces. What would it look like? Well, we already answered this one:

public interface IUnityContainer

{

    //...

    IUnityContainer RegisterType(Type from, Type to, string name, LifetimeManager lifetimeManager);

}

Oh yeah! We just removed 11 methods out of 39. But now what? Will we put the burden on the client of this interface to always call RegisterType with all 4 parameters? Nah...

 

Extension Methos as Overloads

What if we leveraged our knowledge of extension methods to ease usage of our new slimmed down interface? What would it look like? Exactly! It would exactly look like what we have in the default implementation of the IUnityContainer interface:

public static class UnityContainerExtensions

{

    public static IUnityContainer RegisterType(this IUnityContainer container)

        where TTo : TFrom

    {

        return RegisterType(container, null, null);

    }

 

    public static IUnityContainer RegisterType(

      this IUnityContainer container, LifetimeManager lifetimeManager)

        where TTo : TFrom

    {

        return RegisterType(container, null, null);

    }

 

    public static IUnityContainer RegisterType(

      this IUnityContainer container, LifetimeManager lifetimeManager)

    {

        return RegisterType(container, null, lifetimeManager);

    }

 

    public static IUnityContainer RegisterType(

      this IUnityContainer container, string name)

        where TTo : TFrom

    {

        return RegisterType(container, null, null);

    }

 

    public static IUnityContainer RegisterType(

      this IUnityContainer container, string name, LifetimeManager lifetimeManager)

        where TTo : TFrom

    {

        return container.RegisterType(typeof(TFrom), typeof(TTo), name, lifetimeManager);

    }

 

    public static IUnityContainer RegisterType(

      this IUnityContainer container, string name, LifetimeManager lifetimeManager)

    {

        return container.RegisterType(typeof(T), null, name, lifetimeManager);

    }

 

    public static IUnityContainer RegisterType(

      this IUnityContainer container, Type t, LifetimeManager lifetimeManager)

    {

        return RegisterType(container, t, null, lifetimeManager);

    }

 

    public static IUnityContainer RegisterType(

      this IUnityContainer container, Type from, Type to)

    {

        return RegisterType(container, from, to, null);

    }

 

    public static IUnityContainer RegisterType(

      this IUnityContainer container, Type t, string name, LifetimeManager lifetimeManager)

    {

        return container.RegisterType(t, null, name, lifetimeManager);

    }

 

    public static IUnityContainer RegisterType(

      this IUnityContainer container, Type from, Type to, LifetimeManager lifetimeManager)

    {

        return container.RegisterType(from, to, null, lifetimeManager);

    }

 

    public static IUnityContainer RegisterType(

      this IUnityContainer container, Type from, Type to, string name)

    {

        return container.RegisterType(from, to, name, null);

    }

}

Now what?

Well now we can use the full range of overloads and keep IUnityContainer interface as small as possible. It is going to make it a lot easier to mock, decorate and implement the interface without losing any capabilities or ease of use.

Also, we've shared the implementation of overloads throughout all implementations, mocks and decorators of IUnityContainer.

Be careful when designing and trimming down interfaces. It is important that there is no logic associated with the overloads; that is; if registering a component without a name would make a difference and wasn't the equivalent of calling RegisterType(null) then this technique isn't necessarily appropriate.

powered by metaPost

Friday, March 28, 2008 1:56:32 AM (Eastern Standard Time, UTC-05:00)  #    Comments [0] -
.net | .net - Extension Methods
# 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);