3.15.2010

Reflecting Type Equivalence

Today, I want to write about another of the new features in .NET 4: Type Equivalence and Embedded Interop Types. This feature allows you to embed type references to interop types in your assembly. In the end, this allows you to avoid deploying interop assemblies.
Anyway, I don't want to go into much detail about this. You can read more about it here Type Equivalence and Embedded Interop Types and here Walkthrough: Embedding Types from Managed Assemblies
What I want to do here is show you how the types get placed in the assembly. This is pretty much just a quick look with reflector in an assembly with embedded COM types.
So here's what I've done to test this:
I've created a simple project, added a reference to MSXML, then in the added reference properties, I've made sure the property "Embed Interop Types" was set to "True" (This is what defines if a reference is to be embedded).
Then I've inserted this small code snippet to use this library:
Note that in the code above I have a comment with the code that I would regular use to create an instance of the DOMDocument class. However you can't use code like this if you wish to use type equivalence. Classes aren't embedded, interfaces are. If you try to use that line of code you'll get the compilation error below.

Now, let's finally look at the compiled assembly with the .NET developer's favorite tool: Reflector.


As you can see above, a small part of the MSXML2 Namespace as been included in our brand new assembly. Note that only the referenced interfaces (along with its own dependencies) by our code were included in the assembly, so this means that not only you avoid redistributing an interop, but you also end up reducing the size of your application dependencies!

3.11.2010

WPF Treeview bound to an xml file monitored for changes

Here's a code snippet of a WPF treeview binding to a xml file, which gets reloaded everytime the xml file is physically changed.

The sample xml file I'm using (located at "C:\data.xml"):


The XAML code:


And finally the C# code-behind code for the same window that monitors the xml file changes and updates the binding accordingly:

3.09.2010

Integrating MEF with a K-means algorithm implementation

When we're interested about a new framework and we want to try it out we usually start by creating a small and simple demo application. Afterwards we start thinking in real-life situations where we could use it. Here, I'll describe my first real-life use of MEF.
I have a small application with a custom implementation of the K-means clustering algorithm. Common implementations of this algorithm attempt to find clusters of points. The cluster points are related by the distance between themselves. In my custom implementation, the points are persons and the "distance" is in fact computed by evaluating a series of constraints. 
Each of these constraints is a distinct class, implementing an IConstraint interface. 
Until know I had the following initialization code for constraints:

Then I had the following code to evaluate the constraints:

Note: In here the "distance" between persons is what I call "concordance rate". The bigger the concordance rate, the "closer" the member is to the cluster.
A few days ago, I had to create a new constraint and when I saw that initialization code and "TODO" comment I decided it was time to change it. After careful thought, I decided MEF was the correct choice. With MEF, I managed to replace this tedious initialization code while reducing the coupling between the concrete constraints and the constraint evaluator.
I've just opened all the Constraint classes and added the attribute [Export(typeof(IConstraint))] like this:

Then I've instructed the ConstraintList property to import all the IConstraints. This is done by marking the property with the attribute [ImportMany(typeof(IConstraint))]. Like this:

Last but not least, I had to instruct the class to compose the constraint list. Like this:

Note that I'm using the using an AssemblyCatalog with the executing assembly on purpose, because I want to load the constraints from the current assembly. If I were to move all the Constraints to another assembly (eg: a separate "Contracts" or "Constraints" assembly) this code would be different.
There you go, just a simple refactoring that allowed me to reduce coupling and remove a TODO comment from my code! And I got to use MEF in a real scenario.

3.08.2010

SQLite "available" for .NET 4.0

If you're a fan of SQLite and you've already started to use VS2010, you've probably noticed that your ADO.NET provider for SQLite no longer works as it should. It's now throwing an exception when you try to load data.
I've had issues with this as well, and yesterday I went back to the forums to see if a solution had already been found. At first sight, it looked I was out of luck, because no new versions were available for download. However, after a better look in their forum, I've found this thread where an installer was supplied to install the provider in VS2010 Beta 2 and VS2010RC. So here's the quick link for download!

I'm guessing this will only be available for download along with the other versions when it is tested against the final VS2010, however, it seems to be working already, so if you're not developing something critical, I guess it's OK to start using it. If this was the only thing stopping you from using VS2010, you're good to go!

3.03.2010

Changing and Rebuilding assemblies to update referenced assemblies

Problem

How to change and rebuild a .NET assembly without having/acessing it's source code just so you can update it's references. Either because you now wish to use a different version of the referenced assembly, or the reference's public key token has changed or because some class has changed namespaces.

Motivation

The problem described above is definitely NOT one of the usual problemns we have to deal on a daily basis. So what motivated this need?
In this case, we're dealing with third party COM libraries. The problem is that the company developing these libraries has not yet released PIA for these libraries. So at some time we felt the urge to create our own normalized interops so that every developer uses the same interop. Otherwise we would have problems deploying all the applications using the different interops. In this process we've also decided to change the namespaces (for normalization purposes).
Recently I had the need to use an additional library (for which no normalized interop had been created). As usual I started by adding a reference to that COM library to my Visual Studio project. By adding a COM reference, Visual Studio automatically creates an interop assembly for us. However in this case, as this library references the other COM libraries previously mentioned, the generated interop wouldn't work, because itself had references to the other COM libraries using the original namespaces, which cannot be found in the other "normalized" interops we're using.
Hence the need to change this interop assembly so that it complies with the other normalized references.

Solution

Knowing that we don't have the source code, the only way of changing an assembly is disassemble it, change the IL code and reassemble it. Also, we'll also re-sign the assembly (which is definetly needed if you wish to install the assembly in the GAC (Global Assembly Cache). Here's the four steps to accomplish this task:


Step 1: Disassemble the assembly

For this first step you'll need to use MSIL Disassembler (also known as ildasm).
Just open a visual studio command prompt and run "ildasm". This will present you with the ildasm GUI. From the File menu, you should open the target assembly and choose "Dump" to create a text file with the assembly MSIL.
Alternatively, for a more direct approach, just run the command:
ildasm targetAssembly.dll /out=targetAssembly.il


Step 2: Change the IL accordingly
Now, it's where you really need to pay attention. This is the tricky part. Depending on what you're trying to achieve, you may have to change different stuff.
First, start by opening the newly generated text file on your favorite text editor.

The referenced assemblies should be among the first lines of the file. Each reference will look something like this:
.assembly extern mscorlib
{
.publickeytoken = (B7 7A 5C 56 19 34 E0 89 ) // .z\V.4..
.ver 4:0:0:0
}

This of course is a reference to the main .NET DLL. Your references will have a different name (here it's "mscorlib"), a different public key token (herer it's "B7 7A 5C 56 19 34 E0 89"), and possibly a different version (here it's "4:0:0:0").
What you need to do next is look for the reference(s) you wish to change and update them accordingly. This can imply changing the name if you've changed the assembly name, changing the public key token if it has changed, or (most usually) the version if you want to bind against a different assembly version. Please note that the version in here is in the following format <major version>:<minor version>:<build number>:<revision>

Now, if you've changed either the assembly name or the assembly base namespace you'll have to do a few massive find and replaces. You'll have to change every type reference to the referenced assemblies you're targetting. Here's why: a simple call to Console.WriteLine, will show up in the MSIL as
IL_0011: call void [mscorlib]System.Console::WriteLine(string)

Look specifically at the "[mscorlib]System.Console" part. It's a reference to the type System.Console in the assembly "mscorlib". This means that type references to types in your target referenced assemblies will have a similar syntax, so if you've changed either the assembly name or the base namespace, you'll have to do a massive find and replace to align both dll's.

Notice that I said "base namespace", because if you do change several namespaces arbitrarly you may have multiplied the number of find and replaces to execute.


Step 3: Reassemble the assembly

Now that you've changed the MSIL to comply with the referenced assemblies, you'll have to reassemble your dll. For this you'll need to use MSIL Assembler (ilasm : the companion tool to the previously mentioned ildasm)

Once again open a visual studio command prompt and execute the command
ilasm /dll targetAssembly.il

This command will produce your brand new targetAssembly.dll


Step 4: Sign the assembly

For this last step we'll use the strong name utility (SN.exe). Also, you'll need an SNK file to sign the assembly. You're probably signing all your assemblies with the same SNK, so you shouldn't have a problem finding it. However if you need to create a new SNK, the command to execute is: "sn -k strongNameKey.snk"
I hope you haven't closed the VS command prompt, because you'll need it to execute the following command to sign your brand new assembly:
sn -Ra targetAssembly.dll strongNameKey.snk

Last but not least, to make sure you didn't forget to do anything, you should go fetch a nice cold beer. If you did forget anything, I'm sure it will come to you while you're drinking!

3.01.2010

Lazy Loading

Today, I'll discuss one simple class that comes bundled with .NET 4.0. It's one of those small features that don't get much attention, but that truly come in handy. In this case, I'm talking about System.Lazy<T>. It's a simple class that provides support for lazy loading, so we no longer need to do those small pieces of code we've been doing throughout the years, whenever we had to deal with resources whose creation revealed to be expensive.

It's a simple class with a simple purpose, therefore it has a very simple usage, which I'll show in the small snippet below.


The code above will produce the following output:
Before bird creation
Creating Bird
I am a Duck
Before eagle creation
Creating Eagle
I am a Eagle



Notice that the Bird class is only instantiated when "bird.Value" and "eagle.Value" are accessed.
In the example above, I've shown:
- the usage of Lazy<T> in a way that instantiation will be done through a call to the default constructor
- the usage of Lazy<T> with a delegate responsible for the creation itself. This delegate will of course only be called at instantiation time (when the Lazy<T> Value property is accessed)

There are also other Lazy<T> constructors that provide further options regarding thread safety, which I will not discuss here.