ReviewUmbrella project

time to read 13 min | 2515 words

imageThe Umbrella project from nVentive. I had the chance of sitting with Francois Tanguay in DevTeach and he showed me a bit about it. I was impressed. Umbrella is the ultimate utility library, using all the advantages C# 3.0 can give it. In fact, I think of it a bit like boost for C#.

I tried to read the code, and it was hard. Because of the util nature of Umbrella, there isn't a lot of context around the code, so you have to parse the code to understand what it is doing. Luckily, there are a lot of unit tests, which allows me to get the context. I strongly recommend reading the tests in stead of the code, they are a far better way to get an understanding on what the project can offer.

I'll go with my usual style, top to bottom, and review what I can.

Binding

This is a concept that I am familiar with from boost. It is also called memoization currying, and is used frequently in functional languages. Here are a few tests, which would explain it much better:

[Fact]
public void Bind_With_One_Param()
{
	Func<int, int> echo = (i) => i;

	var always10 = echo.Bind(10);
	Assert.Equal(10, always10());
}

[Fact]
public void Bind_First_With_Two_Params()
{
	Func<double, double, double> power = Math.Pow;

	var twoToTheN = power.BindFirst(2.0);
	Assert.Equal(1024.0, twoToTheN(10.0));
}
[Fact]
public void Bind_Chaining()
{
	Func<int, int, int, int, long> func = (a, b, c, d) => a + b + c + d;

	var chain = func.BindFirst(1).BindFirst(2).BindFirst(3).Bind(4);
	Assert.Equal(func(1, 2, 3, 4), chain());
}

If you are working with delegates a lot, this is a really nice way to handle that.

Clock

This is a simple abstraction (IClock, SystemClock, FreezedClock) over the current time, which allows you to play around with time with total disregard to the system time. Basically, an abstraction on top of DateTime.Now. The main goal is usually to enable unit testing, but I have found this approach to be very useful for handling out of time processing. What does this mean? If I want to process payroll for February, I should be able to do so, and all calculations should be set to whatever date I am talking about, not the current date. (In fact, in such systems, there is usually the target date and effective date, both of which are used to calculate various things, but I digress.)

Collections

Collections are important, no doubt about that, and Umbrella has a lot to offer there. The first interesting example is automatic conversion between types, supported by the CollectionAdapter. Here is the test that shows how this works:

[Fact]
public void CanConvertBetweenCollectionsTypes()
{
	var ints = new List<int>();
	ICollection<string> strings = new CollectionAdapter<int, string>(
		ints,
		Funcs<string, int>.Convert,
		Funcs<int, string>.Convert);

	strings.Add("1");
	Assert.Equal(1, ints[0]);
}

Note the Funcs.Convert calls, we will discuss them later. The abstraction is quite complete and very useful. This is also a good way of implementing covariance with generics, I think.

There is a wealth of extension methods for dealing with collections. The most important one, as far as I am concerned, is the AddRange over ICollection<T>. I keep wanting that, and it is only there for List<T>. Having it as an extension method is sweet.

[Fact]
public void AddRange_And_ReplaceWith()
{
    ICollection<int> collection = new List<int>();
    
    collection.AddRange(new int[] { 1, 2 });

    collection.ReplaceWith(new int[] { 3, 4 });

    Assert.Equal(2, collection.Count);
    Assert.Equal(3, collection.ElementAt(0));
    Assert.Equal(4, collection.ElementAt(1));
}

Another interesting extension method is Subscribe. I don't like the name, because it has nothing to do with what the code does, but it is a really nice idea nonetheless:

[Fact]
public void Subscribe()
{
	using (collection.Subscribe(1))
	{
		Assert.Equal(1, collection.Count);
	}
	Assert.Empty(collection);
}

Inside the using block, the collection has the element, but during dispose, it is removed. I think that the reason it is called this way is that it is being used by ObservableExtensions (later).

Dictionary also get some love, with FindOrCreate and GetValueOrDefault, both of which are very welcome. Enumerable get a much needed ForEach extension method, as well as other interesting bits, ranging from bool None(predicate) to checking if it is empty to IndexOf, etc. LazyList make an appearance, as it should.

What I find very interesting is SyncronizedDictionary. It is interesting because of the way it is implemented, and because dictionaries are almost always a source of hard to realize threading issues in many applications. The implementation made me laugh, however:

public TValue this[TKey key]
{
    get { return Lock.Read(item => item[key]); }
    set { Lock.Write(item => item[key] = value); }
}

It made me laugh because it is so simple. I traced down the implementation, and I liked it. It comes down to using Reader Writer Lock, which is what you are supposed to be doing. Obvious Umbrella has attained its critical mass.

Components

Ubmrella is also big enough to include its own Service Locator implementation, which can be plugged into an IoC container. I think that I'll skip this part.

Composites

All the building blocks for the composite patterns are here, and in a very interesting fashion. Take a look at this:

public class CompositeFoo : Composite<IFoo>, IFoo
{
    #region IFoo Members

    public void Do(int i)
    {
        Items.ForEach(item => item.Do(i));
    }

    #endregion
}

And now we can use this like this:

[Fact]
public void SelectMany()
{
	var foo = new CompositeFoo
	          	{
	          		new Foo(),
	          		new OtherFoo(),
	          		new OtherFoo(),
	          		new CompositeFoo
	          			{
	          				new Foo(),
	          				new OtherFoo()
	          			}
	          	};
	IEnumerable<IFoo> items = foo.SelectMany();

    Assert.Equal(5, items.Count());
    Assert.Equal(2, items.OfType<Foo>().Count());
    Assert.Equal(3, items.OfType<OtherFoo>().Count());
}

I don't use composites all that much, but it is an elegant approach.

Conditions

You can almost classify this as an extension of the composite pattern, by allowing to compose conditions. This is really useful when you have to build complex conditions are runtime.

[Fact]
public void True()
{
    IMessage<Null, bool> lhs = new Message<Null, bool>(notUsed => true);
    IMessage<Null, bool> rhs = new Message<Null, bool>(notUsed => true);

    var andMessage = lhs.And(rhs);

    Assert.True(andMessage.Send());
}

However, did you note the IMessage? I will get to that in a bit, and we will discuss this, it is an important part of Umbrella, but not one I like.

Containers

Couldn't figure out what this is supposed to do. Seems to be relation to the service locator impl.

Contracts

Couldn't figure out what this is supposed to do. Seems to be relation to the service locator impl.

Conversions

There are some nice things there, mostly accessible via Conversion().To<TTarget>(), handling Enums is nice:

[Fact]
public void StringFromEnum()
{
    Assert.Equal("Cancelled", Status.Cancelled.Conversion().To<string>());
    Assert.Equal("VER", Status.Verified.Conversion().To<string>());
}

public enum Status
{
    [Description("VER")]
    Verified,
    Cancelled
}

Or standard type conversions:

[Fact]
public void CanConvertInt32ToString()
{
    Assert.Equal("1", 1.Conversion().To<string>());
}

[Fact]
public void CanConvertStringToInt32()
{
    Assert.Equal(1, "1".Conversion().To<int>());
}

Decorator

Again, the building blocks for the decorator pattern. This time, I don't see much use of this, since it doesn't seem to provide much value.

Equality

Provide a set of extension methods that extend equality comparisons. Mostly over enumerables and the like, from a brief look.

Events

There are the expected Raise() set of extension methods, but I find Observe and Notify far more interesting:

using(order.Observe(UpdateForm))
{
	form.Show();
}

And:

public int Value
{
    get { return value; }
    set
    {
        this.value = value;
        this.Notify(PropertyChanged, item => item.Value);
    }
} 

During the using statement, all NotifyPropertyChanged events will be captured. This is nice. The Notify() will handle property notifications without using strings. I don't deal much with INotifyPropertyChanged, however, so I care little for this.

There is also an implementation of observable, which may be useful. Again, this is not something I tend to use.

Expressions

Linq expressions are immutable, which make it a harder to build them. Umbrella solve this by giving us editable expressions, which are builders on top of normal extensions. Nice.

Extensions

This is a very loaded term in a utility project, and it contains a lot of things.  Some of the things I liked are date handling:

[Fact]
public void Equal()
{
    DateTime x = new DateTime(2008, 2, 1);
    DateTime y = new DateTime(2008, 2, 2);

    Assert.True(x.Equal(y, DateTimeUnit.ToMonth));
    Assert.False(x.Equal(y, DateTimeUnit.ToDay));
}

[Fact]
public void Truncate()
{
    Assert.Equal(new DateTime(2008, 2, 1), new DateTime(2008, 2, 2).Truncate(DateTimeUnit.ToMonth));
}

There are a lot of things around date, but I think that this is a representative method:

public static DateTime BeginningOfWeek(this DateTime self)
{
	return (self - self.DayOfWeek.DaysSince(Extensions.WeekBeginsOn).Days())
				.BeginningOfDay();
}

There are also the standard (by now), "foo".IsNullOrEmpty() and "foo".HasValue(), additions to

I can't figure out the concept of Extension Points, however. Or, to be rather exact, I can't see what value it brings to the table.

What is really sweet is the handling of bit manipulation:

[Fact]
public void Enum_Add()
{
    BindingFlags flags = BindingFlags.Public;
    flags = flags.Add(BindingFlags.NonPublic);

    Assert.Equal(BindingFlags.Public | BindingFlags.NonPublic, flags);
}

[Fact]
public void Enum_Remove()
{
    BindingFlags flags = BindingFlags.Public | BindingFlags.NonPublic;
    flags = flags.Substract(BindingFlags.NonPublic);

    Assert.Equal(BindingFlags.Public, flags);
}

And the correspond read approach:

[Fact]
public void Enum_ContainsAll()
{
    BindingFlags flags = BindingFlags.Public | BindingFlags.NonPublic;

    Assert.True(flags.ContainsAll(BindingFlags.Public));
    Assert.True(flags.ContainsAll(BindingFlags.NonPublic));
    Assert.True(flags.ContainsAll(BindingFlags.Public | BindingFlags.NonPublic));

    Assert.False(flags.ContainsAll(BindingFlags.Public | BindingFlags.Instance));
    Assert.False(flags.ContainsAll(BindingFlags.Instance));

}

[Fact]
public void Enum_ContainsAny()
{
	BindingFlags flags = BindingFlags.Public | BindingFlags.NonPublic;

	Assert.True(flags.ContainsAny(BindingFlags.Public));
	Assert.True(flags.ContainsAny(BindingFlags.NonPublic));
	Assert.True(flags.ContainsAny(BindingFlags.Public | BindingFlags.NonPublic));
	Assert.True(flags.ContainsAny(BindingFlags.Public | BindingFlags.Instance));

	Assert.False(flags.ContainsAny(BindingFlags.Instance));
}

Factories

Seems to be relation to the service locator impl.

Locator

This is the service locator impl, I am ignoring that.

Messages

Messages are pretty important in Umbrella. They are defined as:

public interface IMessage<TRequest, TResponse>
{
    TResponse Send(TRequest request);
}

I strongly disagree with the term message here, however. A message in inanimate object, it doesn't act on its own. Messages in Umbrella are actions. In fact, the default implementation of a message is around a Func<TRequest, TResponse>.

Once you have those messages, however, you can start dealing with them in interesting ways. As a simple example, you can create a DisposableMessage, which will wrap another message and call Send() on it. Or bind the output of one message to the input of another, or simply chain them all together. A lot of the actions inside Umbrella are happening using those messages.

Reflection

This is a probably my favorite part in Umbrella. It abstract away all the gory reflection details:

[Fact]
public void Instance()
{
    Foo foo = new Foo();

    IReflectionExtensionPoint fooReflection = foo.Reflection();

    Assert.Equal(foo.I, fooReflection.Get("i"));

    fooReflection.Set("i", 2);

    Assert.Equal(2, foo.I);

    Assert.Equal(2, fooReflection.Get("I"));

    fooReflection.Set("I", 3);

    Assert.Equal(3, foo.I);

    Assert.Equal(3, fooReflection.Get("GetI"));

    fooReflection.Set("SetI", 4);

    Assert.Equal(4, foo.I);
}

Leaving aside how much easier it make it to write the code, it also means that I now have an extension point to replace how it works if I need to. Nice.

Security

This appears to be based on contracts, which I already stated that I don't understand.

Serialization

This is cool, and I think that I figured out what extension point is for. Take a look at the code:

int instance = 1;
instance.Serialization().Binary(new MemoryStream());
instance.Serialization().Xml(new MemoryStream());

This is a general pattern of usage in the code, you have an extension method that return an ExtensionPoint<T>, on top of which you can add additional extension methods, and build up a nice API in this fashion. It also make this big library much more discoverable.

Sources

A way to get values, not sure what it is for, however.

Threading

This give us a way to handle locking in a really nice fashion, as we have already seen with SyncronizedDictionary. Just create a SynchronizableLock<T> and start calling Lock.Read(lambda) and Lock.Write(lambda).

I really like this.

Validation

This is bare bone at the moment, but it is looking really nice. Check this out:

[Fact]
public void String_NotNullOrEmpty_WithNull()
{
	string value = null;

	var ex = Assert.Throws<ArgumentNullException>(() => value.Validation().NotNullOrEmpty("value"));
	Assert.Equal("value", ex.ParamName);
}

Values

Again, this is making heavy use of messages and and I am pretty sure that I don't understand the intended usage. Digging through the code I found some interesting ideas about registering for disposal, which looks interesting. Basically, you can do the following inside classes that inherit from container:

Disposable.Add(new MyLock());

And it will be disposed when the container is disposed. Nice.

Web

Contains implementations of sources on session and web principals. I don't get sources, so I am not sure what I can make of this.

Summary

This has been a brief overview, but no means have I gone through the whole thing. Umbrella is big. At first, extension points are very strange, but they make sense once you realize how Umbrella is architected. They allow to extend a type and preserve the original value nicely.

There are some things that I really like, (Reflection, SyncronizedDictionary, Lock.Write) and some I can't figure out (sources, values, etc). I strongly suggest reading through the code, if only to get some ideas about patterns that are useful for C# 3.0.

More posts in "Review" series:

  1. (06 Sep 2018) Summary
  2. (05 Sep 2018) When the data hits the disk
  3. (04 Sep 2018) Reading data from disk
  4. (03 Sep 2018) The hash structure
  5. (31 Aug 2018) Working with the file system
  6. (30 Aug 2018) Digging into the C++ impl
  7. (29 Aug 2018) Let’s check these numbers
  8. (28 Aug 2018) Let’s start with managed code
  9. (27 Aug 2018) Reading the paper