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, September 30, 2009

logo altnet

Le 22 octobre prochain Matthieu animera une présentation organisée par le groupe ALT.NET de Montréal. Pour ceux qui ne connaissent pas ALT.NET, le groupe montréalais est tout jeune mais il fait parti d’un mouvement plus large . Bien que peu formalisée cette communauté est vivante : elle organise des conférences réelles ou virtuelles, une liste de discussion technique et bien sûr des évènements locaux autour des bonnes pratiques logiciels.

Le sujet de cette présentation sera Umbrella :

vue sur hanselman.com et ayende.com

Umbrella n’est pas un nième framework, il n’y a pas de setup, juste une assemblie de 56k avec plein de goodies !

Voici un petit avant-goût de ce que vous allez voir, Umbrella est une bonne façon d’apprendre : en connaissant ses limites, on découvre d’autres choses sur le framework .NET.

IEnumerable & Dictionnaire : les méthodes qu’on a toujours voulues avoir sans jamais avoir oser les demander !

  1: maCollection.ForEach(item => Console.WriteLine(item + 1));
  2: maCollection.Remove(item => item == "1");
  3: var maybe = monDictionnaire.GetValueOrDefault("AD");

Exécuter une action à la fin d’un bloc using :

  1: public static void DummyMethod()
  2: {
  3: 	using (TimeMethod())
  4: 	{
  5: 		Console.WriteLine("I'm in the method...");
  6: 		// Do something...
  7: 	}
  8: 	//The approximate time spent in the using block has been displayed at the end 
  9: }
 10: public static IDisposable TimeMethod()
 11: {
 12: 	var w = Stopwatch.StartNew();
 13: 	Action stopTimer = () => {
 14: 	   Console.WriteLine(w.Elapsed);
 15: 	};
 16: 	return stopTimer.ToDisposable();
 17: }
 18: 

Ou avoir le Cast facile :

  1: public static IEnumerable<Type> EnumPlugins(Assembly assembly)
  2: {
  3:     return from pluginType in assembly.GetTypes()
  4: 	   where pluginType.Is<IPlugin>()
  5:        select pluginType;
  6: }
  7: 

Mais il y a encore plein d’autres choses à voir.

Vous trouverez les détails sur le site de Alt.NET Montréal et n’oubliez de vous inscrire !

Wednesday, September 30, 2009 6:57:12 AM (Eastern Standard Time, UTC-05:00)  #    Comments [0] -

# Sunday, April 26, 2009

More fun with dictionaries on the way. We’ve seen how to read from a dictionary with the GetValueOrDefault() extension method but that’s not enough.

We usually need a way to add items to a dictionary if they aren’t already there. Here’s a simple example of a caching mechanism that relies on in-memory dictionaries:

Given:

public interface IOrderRepository

{

    Order GetOrderById(int id);

}

 

public class Order

{

    public int Id { get; set; }

}

 

A simple caching mechanism can be obtained using the Decorator pattern:

public class CacheOrderRepository : IOrderRepository

{

    private Dictionary<int, Order> orders = new Dictionary<int, Order>();

 

    public CacheOrderRepository(IOrderRepository repository)

    {

        Repository = repository;

    }

 

    public IOrderRepository Repository

    {

        get;

        private set;

    }

 

    #region IOrderRepository Members

 

    public Order GetOrderById(int id)

    {

        Order order;

 

        if (!orders.TryGetValue(id, out order))

        {

            order = Repository.GetOrderById(id);

            orders.Add(id, order);

        }

 

        return order;

    }

 

    #endregion

}

 

What basically happens here is that we’ll first try to find the value from the local dictionary (hence the cache) and if not present, go to the real repository to fetch the value and then create an entry in the local cache with the result. So what the code really wants to say is:

public Order GetOrderById(int id)

{

    return orders.FindOrCreate(id, () => Repository.GetOrderById(id));

}

 

A simple refactoring of the previous implementation into an extension method would lead to something like:

 

public static class DictionaryExtensions

{

    public static TValue FindOrCreate<TKey, TValue>(

        this IDictionary<TKey, TValue> items, TKey key,

        Func<TValue> factory)

    {

        TValue value;

 

        if (!items.TryGetValue(key, out value))

        {

            value = factory();

            items.Add(key, value);

        }

 

        return value;

    }

}

 

Note again that we’re extending the minimal interface, IDictionary<T>, and leveraging an existing delegate type, Func<T>.

() => “Francois”

Sunday, April 26, 2009 6:28:29 PM (Eastern Standard Time, UTC-05:00)  #    Comments [2] -
.net - Extension Methods | Umbrella
# Friday, April 24, 2009

So far, we’ve seen useful tricks to extend basic collection types like IEnumerable<T> and ICollection<T> but more complex collections deserve attention too!

 

Let’s look at IDictionary<T>. Here’s some code I stumbled upon recently; it is a partial implementation of IDataErrorInfo:

 

public class Order : IDataErrorInfo

{

    private IDictionary<string, string> errors =

        new Dictionary<string, string>();

 

    private decimal amount;

 

    public decimal Amount

    {

        get { return amount; }

        set

        {

            amount = value;

 

            if (amount <= 0)

            {

                errors["Amount"] = "Amount has to be larger than 0";

            }

            else

            {

                errors.Remove("Amount");

            }

        }

    }

 

    #region IDataErrorInfo Members

 

    public string Error

    {

        get { return null; }

    }

 

    public string this[string columnName]

    {

        get

        {

            if (errors.ContainsKey(columnName))

            {

                return errors[columnName];

            }

            else

            {

                return null;

            }

        }

    }

 

    #endregion

}

 

The interesting part is:

if (errors.ContainsKey(columnName))

{

    return errors[columnName];

}

else

{

    return null;

}

 

What’s the intent of this code? Pretty obvious isn’t it? It checks whether the dictionary has a value for a given key, then returns the value. If the key isn’t found, it returns the default value. This is similar to how the Nullable<T> type works:

int? index = null;

 

int indexValue = index.GetValueOrDefault();

 

Here, for obvious reasons, indexValue’s value will equal 0. But what’s interesting is the GetValueOrDefault() method. It clearly expresses the intent as opposed to:

int indexValue = index == null ? 0 : index.Value;

 

The same thing could apply to dictionaries but hasn’t been provided as part of the Base Class Library:

public string this[string columnName]

{

    get { return errors.GetValueOrDefault(columnName); }

}

 

Here’s Umbrella’s implementation:

public static class DictionaryExtensions

{

    public static TValue GetValueOrDefault<TKey, TValue>(

        this IDictionary<TKey, TValue> dictionary,

        TKey key)

    {

        return GetValueOrDefault(dictionary, key, default(TValue));

    }

 

    public static TValue GetValueOrDefault<TKey, TValue>(

        this IDictionary<TKey, TValue> dictionary,

        TKey key,

        TValue defaultValue)

    {

        return GetValueOrDefault(dictionary, key, () => defaultValue);

    }

 

    public static TValue GetValueOrDefault<TKey, TValue>(

        this IDictionary<TKey, TValue> dictionary,

        TKey key,

        Func<TValue> defaultValueProvider)

    {

        TValue value;

 

        if (!dictionary.TryGetValue(key, out value))

        {

            value = defaultValueProvider();

        }

 

        return value;

    }

}

 

The first method is an overload that will return default(T) if a default value is required.

The second method takes the defaultValue as a parameter

The third method contains the actual implementation and relies on a delegate to obtain the value since the defaultValue could either take some time to process or cannot be known in advance.

Again, these extension methods are small helpers to reduce the friction of th BCL. They are not meant to completely change the programming paradigm. They aren’t intrusive either. They should increase predictability of the source code with a side effect of decreasing the total lines of code count.

() => “Francois”

Friday, April 24, 2009 7:23:50 AM (Eastern Standard Time, UTC-05:00)  #    Comments [1] -
.net - Extension Methods | Umbrella
# Thursday, April 23, 2009

There is code what we type over and over again without realizing how many mistakes can be made in a few lines. Let’s take the example where we want to remove items from a collection. Intuitively, the code should be something like:

var orders = new List<Order> {

    new Order { Total = 100 },

    new Order { Total = 150 },

    new Order { Total = 200 }};

 

foreach (var order in orders)

{

    if (order.Total > 100)

    {

        orders.Remove(order);

    }

}

 

However, this will fail miserably with an “InvalidOperationException: Collection was modified; enumeration operation may not execute.”

In fact, it doesn’t fail on the Remove() call, it fails on the MoveNext() as we can’t enumerate a modified collection or can’t modify a collection while enumerating. In order to work correctly, we learned that we need to first keep track of the items to remove and then enumerate through those and remove them from the collection:

var orders = new List<Order> {

    new Order { Total = 100 },

    new Order { Total = 150 },

    new Order { Total = 200 }};

 

var ordersToRemove = new List<Order>();

 

foreach (var order in orders)

{

    if (order.Total > 100)

    {

        ordersToRemove.Add(order);

    }

}

 

foreach (var order in ordersToRemove)

{

    orders.Remove(order);

}

 

Wow! That is a huge amount of code. At least it can be refactored in a generic extension method:

public static class CollectionExtensions

{

    public static void Remove<T>(

        this ICollection<T> collection,

        Func<T, bool> predicate)

    {

        var itemsToRemove = new List<T>();

 

        foreach (var item in collection)

        {

            if (predicate(item))

            {

                itemsToRemove.Add(item);

            }

        }

 

        foreach (var item in itemsToRemove)

        {

            collection.Remove(item);

        }

    }

}

 

And then be used as:

orders.Remove(o => o.Total > 100);

 

In Umbrella, we go the extra mile and “simplify” the implementation of the Remove() extension method and dog food our own extensions:

public static void Remove<T>(

    this ICollection<T> collection,

    Func<T, bool> predicate)

{

    collection

        .Where(predicate)

        .ToList()

        .ForEach(item => collection.Remove(item));

}

 

What basically happens here is that we:

  1. Filter the original collection to keep only the items to remove (Sounds familiar?)
  2. Copy those items to a temporary list (Remember?)
  3. For each of those items, call Remove() on the original collection (Rings a bell?)

() => “Francois”

Thursday, April 23, 2009 9:03:24 AM (Eastern Standard Time, UTC-05:00)  #    Comments [1] -
.net - Extension Methods | Umbrella
# Wednesday, April 22, 2009

Some extension methods in Umbrella are simple but yet useful. It usually ends up being exiting methods from the Base Class Library that weren’t defined on the simplest interface required but more as a helper method on more concrete types:

Let’s start with the most straighforward example:

Given:

public class Order

{

    public decimal Total { get; set; }

}

 

We’ll usually see something like:

var orders = new List<Order>();

 

var order = new Order();

orders.Add(order);

 

But when the item to add to the collection has a default constructor, we could have a shorter syntax:

var orders = new List<Order>();

 

var order = orders.AddNew();

But AddNew() isn’t a member of List<T>. Have you guessed how AddNew() is implemented? Using extension methods, of course but what should be extended? List<T>? It is actually ICollection<T> as it is the interface containing the Add method.

public static class CollectionExtensions

{

    public static T AddNew<T>(this ICollection<T> items)

        where T : new()

    {

        T item = new T();

 

        items.Add(item);

 

        return item;

    }

}

 

A generic constraint on T having a default constructor is required so that new() can be called.

I mentioned that some helper methods have been defined on concrete types on the past where now, with extension methods, they could be extending simple interfaces. It is the case of List<T>.AddRange():

var orders = new List<Order>();

 

var newOrders = new List<Order> {

    new Order { Total = 100 },

    new Order { Total = 150 },

    new Order { Total = 200 }};

 

orders.AddRange(newOrders);

 

What AddRange logically does, is call Add for each new item. If we were to boil it down to its simplest form:

public static class CollectionExtensions

{

    public static void AddRange<T>(

      this ICollection<T> collection,

      IEnumerable<T> items)

    {

        items.ForEach(collection.Add);

    }

}

 

Don’t get confused by the “collection.Add” syntax, it is the method group syntax. The equivalent lambda expression would be:

items.ForEach(item => collection.Add(item));

 

That’s it for Part 2!

() => “Francois”

Wednesday, April 22, 2009 11:19:16 AM (Eastern Standard Time, UTC-05:00)  #    Comments [0] -
.net - Extension Methods | Umbrella
# Tuesday, April 21, 2009

For the last couple of days, Michael, a friend of us has changed his Messenger tagline to: “If the code speaks for itself, don’t interrupt”.

It expresses clearly the intent of Umbrella… To allow the developer to create code that speaks for itself as opposed to code that requires a translator.

Let’s take the following code:

static void Main(string[] args)

{

    foreach (var arg in args)

    {

        if (!string.IsNullOrEmpty(arg))

        {

            Console.WriteLine(arg);

        }

    }

 

    Console.ReadLine();

}

 

If we were to “listen” to the code, it would say that for each arg in the args list, if the string has a value, it should be displayed in the console.

So in order to let the code speak more clearly, we should be able to write something like:

static void Main(string[] args)

{

    args.Where(a => a.HasValue())

        .ForEach(a => Console.WriteLine(a));

 

    Console.ReadLine();

}

 
It might not show as there is not much going on, but the intent is clearer.
 
Even if the following two statements are equivalent, one is more focused and concise:
 

!string.IsNullOrEmpty(arg)

 

arg.HasValue()

 

In order to obtain this simpler syntax, we simply leverage the extension methods paradigm from C# 3.0 and LINQ for the Where clause:

public static class StringExtensions

{

    public static bool HasValue(this string value)

    {

        return !string.IsNullOrEmpty(value);

    }

}

 

Remember, to code an extension it takes 3 ingredients:

  1. A static class
  2. A static method
  3. The this modified on the first method parameter

As you probably guessed, the ForEach implementation is as simple:

public static class EnumerableExtensions

{

    public static void ForEach<T>(this IEnumerable<T> items, Action<T> action)

    {

        foreach (var item in items)

        {

            action(item);

        }

    }

}

 

Two important things to node with the ForEach extension:

  1. We’ve extended the minimal interface required (IEnumerable<T>)
  2. We’ve leveraged the existing Action<T> delegate as opposed to defining a custom one

In the following posts, we’ll show how much more the code can say!

() => “Francois”

Tuesday, April 21, 2009 10:30:26 PM (Eastern Standard Time, UTC-05:00)  #    Comments [1] -
.net - Extension Methods | Umbrella
Search
Archive
<September 2009>
SunMonTueWedThuFriSat
303112345
6789101112
13141516171819
20212223242526
27282930123
45678910
Statistics
Total Posts: 98
This Year: 28
This Month: 1
This Week: 1
Comments: 17
Sign In