Introduction

These utility classes are piece of code I gathered from internet the last years. And I'm sure you'll find classes you'll use everyday here.

My goal is not to create a library, but just to gather cool piece of code at the same place so people can use them by copy pasting, without any dependencies.

If that's not already the case, I highly recommend you to gather cool piece of code you see on the web and having your personal framework correctly saved in a code repository somewhere. It will save you lots of time.

Some of you will tell that you don't have to reinvent the weel, and that's right.

But the point is that sometimes you have very specific and simple (but not easy) tasks to do and don't want the burden of yet another library. Moreover you are the most likely person who will want to reuse these classes later : you already know where to find them, how they behave, what pitfalls they have, and what you learnt by using them.

I've kept original comments in the code, so sometimes, you will be able to find the original author.

I want to thanks people who shared these classes on the net, and who saved me lots of time and money. The best thing I can do is to spread their work.

All unit tests or code snippet presented here pass.

Content

11 useful classes

LogonUser : how to impersonate a user, the easy way

Sometimes, you will need to run a piece of code with the windows credential of another user to use his ACL rights. This is called impersonation. Here is an example.

[TestMethod]
public void CanUndoImpersonation()
{
	var oldName = Impersonation.CurrentUserName;
	using(Impersonation.Impersonate(TestUser.UserName, TestUser.Password))
	{
		AssertEx.ShouldContains(TestUser.UserName, Impersonation.CurrentUserName);
		AssertEx.ShouldNotContains(TestUser.UserName, oldName);
	}
	AssertEx.ShouldContains(oldName, Impersonation.CurrentUserName);
}
	

Were Impersonation.CurrentUserName is

public static String CurrentUserName
{
	get
	{
		return System.Security.Principal.WindowsIdentity.GetCurrent().Name;
	}
}

Pitfalls to be aware of

Some "funny" bugs I have learnt the hard way and to be aware of...

[TestMethod]
public void LazyAssemblyInAImpersonatedSecurityContextWithoutFileRightsThrows()
{
	using(Impersonation.Impersonate(TestUser.UserName, TestUser.Password))
	{
		AssertEx.Throws<FileLoadException>(() =>
		{
			Class1 hello = new Class1();
		});
	}
}

In this piece of code, the code throws because Class1, which is in another assembly, is loaded when the lambda expression inside AssertEx.Throws is "jitted". Which is... under TestUser's credentials who does not have read right on the assembly file !

This code works fine:

[TestMethod]
public void LoadAssemblyBeforeImpersonatingSoYouDontLazyLoadInTheWrongSecurityContext()
{
	Class1 test = null;
	using(Impersonation.Impersonate(TestUser.UserName, TestUser.Password))
	{
		AssertEx.DoesntThrow(() =>
		{
			Class1 hello = new Class1();
		});
	}
}

But I have another surprise for you, and I suspect it's a bug of the .NET framework (not sure if it's by design).

If you tried to load an assembly first on the behalf of a user without the read right on it then you'll never be able to load it later.

[TestMethod]
public void AndYouCantEvenRetryToLoadAssemblyInTheRightContext()
{
	var oldAccount = Impersonation.CurrentUserName;
	using(Impersonation.Impersonate(TestUser.UserName, TestUser.Password))
	{
		AssertEx.Throws<FileLoadException>(() =>
		{
			Class1 hello = new Class1();
		});
	}
	Assert.AreEqual(oldAccount, Impersonation.CurrentUserName);
	AssertEx.Throws<FileLoadException>(() =>
	{
		Class1 hello = new Class1();
	});
}

I've seen that when I saw that my two previous tests would not pass when I runned them at the same time...

PathUtil : how to get a relative path from an absolute folder

This task is really simple... but not easy to code ! Here is how you can use it.

[TestMethod]
public void CanGetRelativePath()
{
	var path = PathUtil.RelativePathTo(@"c:\toto\titi", @"c:\toto\titi\tutu.txt");
	Assert.AreEqual("tutu.txt", path);
	path = PathUtil.RelativePathTo(@"c:\toto\tata", @"c:\toto\titi\tutu.txt");
	Assert.AreEqual(@"..\titi\tutu.txt", path);
}

How cool is that ? but be careful to use "\" and not "/" in the path... you have the code if you want to fix that.

LambdaExtensions : extension methods to extract a property name from an expression.

This one is about avoiding magic string of property name in your code, so you don't have stupid error after refactoring.

[TestMethod]
public void CanGetPropertyName()
{
	TestClass test = new TestClass();
	var propertyName = LambdaExtensions.GetPropertyName(() => test.ReferenceMember);
	Assert.AreEqual("ReferenceMember", propertyName);
	propertyName = LambdaExtensions.GetPropertyName(() => test.ValueMember);
	Assert.AreEqual("ValueMember", propertyName);
}

NotifyPropertyChangedBase : a concrete use case of LambdaExtensions.

If you are doing some WPF or Silverlight development, I'm sure you appreciate how to declare a property of a ViewModel with a code snippet :

public class ViewModel : NotifyPropertyChangedBase
{
	private int _Value;
	public int Value
	{
		get
		{
			return _Value;
		}
		set
		{
			if(value != _Value)
			{
				_Value = value;
				OnPropertyChanged(() => this.Value);
			}
		}
	}
}

And here is the test to be sure it works correctly as expected:

[TestMethod]
public void TypedOnPropertyChangedFireCorrectly()
{
	ViewModel vm = new ViewModel();
	bool fired = false;
	vm.PropertyChanged += (s, a) =>
	{
		Assert.AreEqual("Value", a.PropertyName);
		fired = true;
	};
	vm.Value = 5;
	Assert.IsTrue(fired);
}

Not convinced ? how do you think about firing easily raising PropertyChanged upon another dependant property ? See the constructor !

public class ViewModel : NotifyPropertyChangedBase
{
	public ViewModel()
	{
		this.AddDependency(() => this.Value, () => this.CalculatedValue);
	}
	private int _Value;
	public int Value
	{
		get
		{
			return _Value;
		}
		set
		{
			if(value != _Value)
			{
				_Value = value;
				OnPropertyChanged(() => this.Value);
			}
		}
	}

	public int CalculatedValue
	{
		get
		{
			return Value + 5;
		}
	}
}

And the test :

[TestMethod]
public void DependantPropertyFireCorrectly()
{
	ViewModel vm = new ViewModel();
	bool fired = false;
	vm.PropertyChanged += (s, a) =>
	{
		if(a.PropertyName == "CalculatedValue")
			fired = true;
	};
	vm.Value = 5;
	Assert.IsTrue(fired);
}

DisposableWrapperExtension : how to dispose effectively a WCF CommunicationObject

You are old enough to know how to use the IDisposable interface you say ? So what do you think about that.

[TestMethod]
public void WCFDisposableProblem()
{
	ServiceHost host = new ServiceHost(new TestService());
	var endpoint = host.AddServiceEndpoint(typeof(ITestService), new WSHttpBinding(), "http://localhost:8372/");
	host.Open();
	var client = new ChannelFactory<ITestService>(endpoint).CreateChannel();
	bool throwAtTheEndOfUsing = false;
	AssertEx.Throws<EndpointNotFoundException>(() =>
	{
		using(((IClientChannel)client))
		{
			client.DoStuff();
			host.Close();
			throwAtTheEndOfUsing = true;
		}
	});
	Assert.IsTrue(throwAtTheEndOfUsing);
}

Here we close the ServiceHost before the client channel, so the client channel throws an exception inside the Dispose method instead of just aborting...

I swear that when you discover this behavior the first time, the only thing you want is to stop programming and just start gardening potatoes in the campaign for the end of your life...

So to keep your pride and love as a developer, use DisposableWrapperExtension, here is how, thanks to a stackoverflow guru.

[TestMethod]
public void CanUseFixDisposable()
{
	ServiceHost host = new ServiceHost(new TestService());
	var endpoint = host.AddServiceEndpoint(typeof(ITestService), new WSHttpBinding(), "http://localhost:8374/");
	host.Open();
	var client = new ChannelFactory<ITestService>(endpoint).CreateChannel();
	using(((IClientChannel)client).FixIDisposable())
	{
		client.DoStuff();
		host.Close();
	}
}

It Dispose, then Abort the channel inside a ThreadPool's thread, so an exception will not crash your AppDomain. (Something I learnt the hard way too...)

EnumExtensions : How to easily manipulate a flag enum.

If boolean arithmetic is not for you, then here is a simple class to manipulate flag enums, for example, with this enum :

[Flags]
public enum ErrorTypes
{
	None = 0,
	MissingPassword = 1,
	MissingUsername = 2,
	PasswordIncorrect = 4
}

You can easily see which flag is on or off :

[TestMethod]
public void CanAppendRemoveAndConsultFlagEnum()
{
	ErrorTypes error = ErrorTypes.MissingPassword;
	Assert.IsTrue(error.Has(ErrorTypes.MissingPassword));
	error = error.Append(ErrorTypes.MissingUsername);
	Assert.IsTrue(error.Has(ErrorTypes.MissingPassword));
	Assert.IsTrue(error.Has(ErrorTypes.MissingUsername));
	Assert.IsTrue(error.Has(ErrorTypes.MissingPassword.Append(ErrorTypes.MissingUsername)));
	error = error.Remove(ErrorTypes.MissingPassword);
	Assert.IsFalse(error.Has(ErrorTypes.MissingPassword));
	Assert.IsTrue(error.Has(ErrorTypes.MissingUsername));
}

ThreadSafeDictionary : how to add an item atomatically, the easy way

A threadsafe Dictionary where you can atomatically add/replace or remove items (You don't need to call ContainsKey before).

[TestMethod]
public void CanDeleteAndRemoveItems()
{
	ThreadSafeDictionary<int, string> dictionary = new ThreadSafeDictionary<int, string>();
	dictionary.MergeSafe(1, "hello");
	dictionary.MergeSafe(2, "hello2");
	Assert.AreEqual(2, dictionary.Count);
	dictionary.RemoveSafe(3);
	dictionary.RemoveSafe(2);
	Assert.AreEqual(1, dictionary.Count);
	Assert.IsTrue(dictionary.ContainsKey(1));
}
The dictionary can be shared between threads safely.

BlockingStream : how to easily mock a client/server communication with a single Stream.

This one, found on StackOverflow, will save your time in unit testing... Especially when you want to simulate client/server (consumer/producer) interaction without any dependency on Socket, WCF, System.Net, or Remoting.

[TestMethod]
public void CanWriteThenRead()
{
	BlockingStream stream = new BlockingStream();
	stream.WriteByte(5);
	var value = stream.ReadByte();
	Assert.AreEqual(5, value);
}
[TestMethod]
public void CanTimeout()
{
	BlockingStream stream = new BlockingStream();
	stream.ReadTimeout = 500;
	Stopwatch watcher = new Stopwatch();
	watcher.Start();
	var value = stream.ReadByte();
	watcher.Stop();
	Assert.IsTrue(500 < watcher.ElapsedMilliseconds);
	Assert.AreEqual(-1, value);
}

WeakCollectionChangedListener : how to stop memory leakage when a listener have shorter life span than the listened object.

SpyObseravableCollection is a class which implements INotifyCollectionChanged, and is used to make my tests easier to read.

[TestMethod]
public void ListenerCanBeGarbageCollected()
{
	var listener = new SpyCollectionListener();
	var source = new SpyObservableCollection();
	WeakCollectionChangedListener weakListener = new WeakCollectionChangedListener(source, listener);
	source.Add(4);
	listener.AssertCollectionChanged();
	WeakReference listenerHandle = new WeakReference(listener);
	listener = null;
	GC.Collect();
	Assert.IsFalse(listenerHandle.IsAlive);
	source.Add(6); //The weak listener unsubscribe on the next event
	source.AssertHasNoListener();
}

WeakObservableCollection : a concrete use case, a wrapper around the listened object and owned by the listener.

The WeakCollectionChangedListener is not really hard to use, however I have another solution easier to read.

I just wrap the source collection inside a WeakObservableCollection. When the WeakObservableCollection is garbage collected, all his listener will unsubscribe from the source collection.

[TestMethod]
public void ListenerOfWeakObservableCollectionCanBeGarbageCollectedWhenWeakCollectionCollected()
{
	var source = new SpyObservableCollection();
	var wrappedSource = new WeakObservableCollection<int>(source);
	var listener = new SpyCollectionListener();
	wrappedSource.CollectionChanged += listener.OnCollectionChanged;
	source.Add(4);
	listener.AssertCollectionChanged();
	WeakReference listenerHandle = new WeakReference(listener);
	listener = null;
	wrappedSource = null;
	GC.Collect();
	Assert.IsFalse(listenerHandle.IsAlive);
	source.Add(6); //The weak listener unsubscribe on the next event
	source.AssertHasNoListener();
}

AssertEx : A class to make your tests readable.

I used this class in my article, sorry about this one, I'm too lazy for writing test about tests (The meta test !) so I'll just remind you where I've used this class in my article.

For example AssertEx.DoesntThrow

[TestMethod]
public void LoadAssemblyBeforeImpersonatingSoYouDontLazyLoadInTheWrongSecurityContext()
{
	Class1 test = null;
	using(Impersonation.Impersonate(TestUser.UserName, TestUser.Password))
	{
		AssertEx.DoesntThrow(() =>
		{
			Class1 hello = new Class1();
		});
	}
}

You may ask : what is the point of this method ? Especially when you see what the implementation is.

public static void DoesntThrow(Action action)
{
	action();
}

There is 2 reasons

First, it shows to the user exactly what behavior I'm expecting. So that he will not give too much attention on the less important like Impersonation.Impersonate(TestUser.UserName, TestUser.Password).

Second, in this specific case, using a lambda expression could alter the result. Remember that in the test just before this one, using a lambda caused the loading of Class1's assembly during the security context of TestUser.

[TestMethod]
public void LazyAssemblyInAImpersonatedSecurityContextWithoutFileRightsThrows()
{
	using(Impersonation.Impersonate(TestUser.UserName, TestUser.Password))
	{
		AssertEx.Throws<FileLoadException>(() =>
		{
			Class1 hello = new Class1();
		});
	}
}

AssertEx.Throws assert that your lambda is throwing the right exception.

Conclusion : what utility class do you own and use frequently ?

Hope you'll like it, but I'm curious about you. What are your best personal utility classes ?

推荐.NET配套的通用数据层ORM框架:CYQ.Data 通用数据层框架
新浪微博粉丝精灵,刷粉丝、刷评论、刷转发、企业商家微博营销必备工具"