Posts Tagged

OzCode

Code Generation Chronicles #1 – Using Fody to Inject KnownType attributes

Code Generation Chronicles

As part of my new year resolutions, I’ve decided to put more effort in learning code generation techniques.

This is the first blog post in a series exploring code generation. Although I won’t always dive into the internals, I do promise that I’ll show examples of what we can achieve with each technique and when it is better to use each one.

Fody

Fody is an open source library for IL weaving. It can generate and manipulate IL code during build time.
Getting Fody is easy – it is available as a Nuget Package and doesn’t require any installation/modification to the build system.

One of the benefits of using Fody is that there is no footprint – since the IL weaving is done during build time, there aren’t any Fody-related assemblies needed at runtime, which could be a good thing if you worried about your project dependencies or the number of assemblies you ship with your product.
And on top of that Fody is highly extensible and there is an active open source community around it.

One example for how Fody can save developer’s time is such extension: “PropertyChanged” which works by placing the ImplementPropertyChanged attribute it provides on a class, it will generate all of the code necessary to fully implement the INotifyPropertyChanged interface in that class.
More extensions can be found here.

Using Fody to add WCF’s KnownType attributes

At work we’ve used a client which was implemented using .Net Remoting as the communication model for it services. At some point, we wanted to exchange .Net Remoting with the more modern WCF. The problem was that a lot of the code base was unmaintainable legacy code, and we’ve wanted to perform as little changes as possible, and reuse as much of the existing architecture as we could.
One of the challenges resided in a WCF quirk, were by default it doesn’t allow passing a derived type of the DataContract type that is defined in the OperationContract.
The way to make derived classes work is done in WCF by adding a KnownType attribute on the base type for each derived type we use.
As an example, if we have a class A and two derived classes B and C, we would have to add two KnownType attributes over class A; one for Class B and one for Class C.

[KnownType(typeof(B))]
[KnownType(typeof(C))]
class A
{
}

class B : A
{
}

class C : A
{
}

Since this scenario was common in the current architecture, we were looking for a way to solve this issue without manually adding KnownType attributes, since it would be easy to miss some or to forget adding the attribute over new derived classes in the future.

In the end we’ve managed to save time and replace the communication layer easily by using Fody for automatically adding KnownType attributes for all derived types on their base classes during build time.

Implementing a Fody extension

If you want to write Fody extension start by cloning the BasicFodyAddin repository. This repository is maintained by the open source community and it simplifies both the implementation and the deployment of the extension as a Nuget Package.
BasicFodyAddin source code contains a Solution with four C# projects:

  1. BasicFodyAddin which will contain the extension
  2. Nuget which is for deploying a Nuget package
  3. Tests for writing unit tests
  4. AssemblyToProcess that is used as a target assembly for testing your mew Fody extension.

We will focus on BasicFodyAddin.

In the BasicFodyAddin project there is a file called ModuleWeaver.cs Go ahead and replace it content with the following code:

using System;
using System.Linq;
using Mono.Cecil;
using Mono.Cecil.Rocks;

namespace KnownTypes.Fody
{
   public class ModuleWeaver
   {
      public ModuleDefinition ModuleDefinition { get; set; }
   
      public void Execute()
      {
      }

      void AddKnownTypeAttributes(ModuleDefinition module, TypeDefinition baseType)
      {
      }

      void RemoveKnowsDeriveTypesAttribute(TypeDefinition baseType)
      {
      }
   }
}

This is the class we will use to implement the extension. The ModuleDefinition property will be populated during build time by Fody and it will contain the target Module for the IL Weaving.
As you have probably noticed, the property is of type ModuleDefinition.
ModuleDefinition is a class representing a MSIL Module in Mono.Cecil which is a library Fody relies on to generate and manipulate IL code. In addition to ModuleDefinition we will use more types it defines such as TypeDefinition.

When using Fody your ModuleWeaver class must be implemented according the following:

  • Be public, instance and not abstract.
  • Have an empty constructor.
  • Have a ModuleDefinition property that will be populated during build.
  • Have an Execute method.

The KnownTypeAttributeWeaver class has three main methods:

  • Execute – Entry point. It calls other methods for performing the IL weaving.
  • AddKnownTypeAttributes – Decorates base types with KnownType attributes.
  • RemoveKnowsDeriveTypesAttribute – Removes KnowsDeriveTypes attributes from base types

Note: A few helper methods will be added down the road.

 

Now create another a new class called KnowsDeriveTypesAttribute.

[AttributeUsage(AttributeTargets.Class, Inherited = false)]
public class KnowsDeriveTypesAttribute : Attribute
{
}

This attribute is for explicitly specifying the base types we want to decorate with KnownType attributes. We could have added KnownType attributes over every base class in the assembly, but we wanted the extra control.

Implementing Execute

public void Execute()
{
   foreach (var type in ModuleDefinition.GetTypes().Where(HasKnownDeriveTypesAttribute))
   {
      AddKnownTypeAttributes(module, type);
      RemoveKnowsDeriveTypesAttribute(type);
   }
}

//A helper method 
//For filtering the types without the KnowsDeriveTypes Attribute.
bool HasKnownDeriveTypesAttribute(TypeDefinition type) => 
   type.CustomAttributes.Any(attr => attr.AttributeType.FullName == typeof(KnowsDerivativeTypesAttribute).FullName);

In Execute we locate all the types decorated with KnowsDeriveTypesAttribute, and we decorate them with KnownType attributes according to their sub types.
After that is done, we remove the KnowsDeriveTypesAttribute as it isn’t necessary anymore.

Implementing AddKnownTypeAttributes

void AddKnownTypeAttributes(ModuleDefinition module, TypeDefinition baseType)
{
   //Locate derived types
   var derivedTypes = GetDerivedTypes(module, baseType);

   //Gets a TypeDefinition representing the KnownTypeAttribute type.
   var knownTypeAttributeTypeDefinition = GetTypeDefinition(module, "System.Runtime.Serialization", "KnownTypeAttribute");

   //Gets the constructor for the KnownTypeAttribute type.
   var knownTypeConstrcutor = GetConstructorForKnownTypeAttribute(module, knownTypeAttributeTypeDefinition);

   //Adds KnownType attribute for each derive type
   foreach (var derivedType in derivedTypes)
   {
      var attribute = new CustomAttribute(constructorToUse);
      attribute.ConstructorArguments.Add(new CustomAttributeArgument(constructorToUse.Parameters.First().ParameterType, derivedType));

      baseType.CustomAttributes.Add(attribute);
   }
}

Let’s break it down.

//Locate derived types
var derivedTypes = GetDerivedTypes(module, baseType);

//Gets a TypeDefinition representing the KnownTypeAttribute type.
var knownTypeAttributeTypeDefinition = GetTypeDefinition(module, "System.Runtime.Serialization", "KnownTypeAttribute");

//Gets the constructor for the KnownTypeAttribute type.
var knownTypeConstrcutor = GetConstructorForKnownTypeAttribute(module, knownTypeAttributeTypeDefinition);

In the code above we are performing three steps:

  1. Finding and retrieving all derived types of the given base type.
  2. Creating a TypeDefinition instance for the KnownType attribute.
  3. Finding and retrieving a constructor for the KnownType attribute.

The first step is done using a helper method called GetDerivedTypes.

Given a module and a type it returns an array of TypeDefinitions, containing all of the types in the given module that derive from the given type

The second step is done using a helper method called GetTypeDefinition.

Given an assembly name and a type name, it returns a TypeDefinition for that type.

The third step is done using a helper method called GetConstructorForKnownTypeAttribute.

Given a ModuleDefinition and a TypeDefinition it returns a the first constructor for that type.

//A helper method. Given a module and a baes type:
//It returns all derived types of that base type.
TypeDefinition[] GetDerivedTypes(ModuleDefinition module, TypeDefinition baseType)
   => module.GetTypes()
         .Where(type => type.BaseType?.FullName == baseType.FullName)
         .ToArray();

//A helper method. Given an assembly and a type name:
//It returns a TypeDefinision for that type.
TypeDefinition GetTypeDefinition(ModuleDefinition module, string assemblyName, string typeName) 
   => module.AssemblyResolver
         .Resolve(assemblyName)
         .MainModule.Types.Single(type => type.Name == typeName);

//A helper method. Given a module and type definition for the KnownType Attribute:
//It returns the constructor for the attribute accepting a System.Type object.
MethodReference GetConstructorForKnownTypeAttribute(ModuleDefinition module, TypeDefinition knownTypeAttributeTypeDefinition)
{
   var constructorMethodToImport = knownTypeAttributeTypeDefinition
                                     .GetConstructors()
                                     .Single(ctor => 1 == ctor.Parameters.Count && "System.Type" == ctor.Parameters[0].ParameterType.FullName);

   return module.Import(constructorMethodToImport);
}

Let’s continue and break down the last part of AddKnownTypeAttributes.

//Adds KnownType attribute for each derive type
foreach (var derivedType in derivedTypes)
{
   var attribute = new CustomAttribute(constructorToUse);
   attribute.ConstructorArguments.Add(new CustomAttributeArgument(constructorToUse.Parameters.First().ParameterType, derivedType));

   baseType.CustomAttributes.Add(attribute);
}

In this part of the code we add a KnownType attribute to the base type for each derived type we previously found.
We are using the KnownType attribute’s constructor that expects the System.Type of the sub class.

Implementing RemoveKnowsDeriveTypesAttribute

This part is straight forward. We locate and then remove the KnowsDeriveTypes attribute from the base type.

void RemoveKnowsDeriveTypesAttribute(TypeDefinition baseType)
{
   var foundAttribute = baseType.CustomAttributes
         .Single(attribute => attribute.AttributeType.FullName == typeof(KnowsDeriveTypesAttribute).FullName);

   baseType.CustomAttributes.Remove(foundAttribute);
}

Unit Tests & Debugging

Unit Tests are always important, especially when writing Fody extensions. We had a good code coverage in the final product, but for this blog post I’ll use Unit Tests solely for debugging purposes, as I will be able to debug the extension by running the Unit Tests in debug mode.

For this post I’ve created two Unit Tests. One for testing the addition of the KnownType attributes and one for testing the removal of the KnowsDeriveTypes attribute. You can view the Unit Tests file here. I’ve also went ahead and added three classes to the AssemblyToProcess project for testing the IL Weaving process.

Even though Fody has a basic logging capability it isn’t always easy to find and view logs in the output window.
Fortunately, at debug time we can use OzCode’s Trace Points feature. I’ve added a trace point at the line which adds a KnownType attribute over base types.

//Trace point was added here in the AddKnownTypeAttributes method.
baseType.CustomAttributes.Add(attribute);

Read More

Using LINQ to abstract Bitwise operations

There are 10 types of developers; those who work in a higher level and depend on abstractions, and those who work with the bits and bytes alongside the bare metal.

As a C# developer, I am one of the former, and I usually try to abstract everything I do. A few weeks ago, I figured out that I can use some of these abstraction techniques to solve “low-level” challenges too. To make a long story short, I was able to utilize LINQ in order to eliminate a rather very complicated bitwise operation.

The mission

A framework for communicating with FPGA cards (Field-Programmable Gate Array), where it sends and receives messages to and from those cards.

One of the framework’s abilities is to serialize and deserialize messages that were sent or received from a FPGA card to and from byte arrays, according to an application-specific protocol.

The structure and the parts each message is composed of vary, and are only determined at runtime.

This looks easy enough

Each message is composed of different parts with different lengths.
By serializing a message, we concatenate each part’s value according to its length in bits.

The following is an example of a message that is composed of 3 parts.

Message
Part 0 Part 1 Part 2
001 1010 00111110000
3 Bits 4 Bits 11 Bits

In this example, “Part 0” has the value of 0x1, “Part 1” has the value of “0xA” and “Part 2” has the value of “0x1F0”.

The framework doesn’t really care about the content of the messages, but rather cares for their structure.

When deserializing a message, we only need the structure or the schema of the message. For each message-part we need to specify its name, index (its order in the message) and length in bits.

I have therefore introduced the following class:

public class LayoutPart
{
	public string Name { get; set; }
	public int Index { get; set; }
	public int BitCount { get; set; }

	public LayoutPart(string name, int index, int bitCount)
	{
		Name = name;
		Index = index;
		BitCount = bitCount;
	}
}

When serializing a message, each message-part has to specify four properties. The three properties of LayoutPart, in addition to the Value of that part.

Here are the classes I have added:

public class MessagePart : LayoutPart
{
     public int Value { get; set; }

     public MessagePart(string name, int index, int bitCount, int value)
          : base(name, index, bitCount)
     {
          Value = value
     }
}

In reality, the content’s type wasn’t known beforehand, and it surly wasn’t always an int, but I decided to use an int in all of my examples to keep them simple.

The relevant API is really simple, and it has two methods; Serialize and Deserialize:

public interface IMessageSerializer
{
    byte[] Serialize(IEnumerable<MessagePart> messageValues);
    IEnumerable<MessagePart> Deserialize(IEnumerabe<LayoutPart> layout,
                                         byte[] bytes);
}

Bitwise operations: This is really ugly

So far so good 😀

After defining the API, I went on and started implementing it.

The following is an example of serializing the message from the example above

Name BitCount Value Value in Bits Value in Bytes
Part 0 3 1 001 00000001
Part 1 4 0xA 1010 00001010
Part 2 11 0x1F0 00111110000 00000001 11110000

The byte array should look like this

Byte 2 Byte 1 Byte 0
00000000 11111000 01010001

The first byte is composed of Part 0 (3 bits), Part 1 (4 bits) and the first bit of Part 2 (11 bits). The second byte is composed of bits 1-8 of Part 2, and the third byte is composed of bits 9-10 of Part 2 with 6 more trailing zeros to complete a byte of 8 bits.

I approached it using the standard-naive way: bitwise operations.
I needed the ability to extract bits from different bytes and bit indexes, then concatenate them together for composing a byte array.

Assuming we are working with System.Int32, how would I extract the n first bits? Easy enough!

value & ((1 << n) - 1)

And to extract the n last bits?

(value >> (32 - n)) & ((1 << n) - 1)

What about extracting n bits that are in the “middle”? This is starting to be more complicated.

((value >> startIndex) & ((1 << n) - 1));

I did a little refactoring and defined them in methods.

long ExtractBits(uint value, int n, int startIndex) =>
                ((value >> startIndex) & ((1 << n) - 1));

long ExtractFirstBits(uint value, int n) => ExtractBits(value, n, 0);

long ExtractLastBits(uint value, int n) => ExtractBits(value, n, 32 - n);

This looks a little bit better. I had to use System.Int64 and system.UInt32 for overflow/underflow safety when performing bitwise operations.

Most importantly, this is an over simplified version of what I needed to do. I also had to consider:

  • Concatenating the results
  • Messaging parts of length exceeding 8 bytes (sizeof(long)). Current implementation won’t work
  • Transfer the results into a byte array
  • Implementing deserialization, which is even harder

I went on and finished the rest of the implementation. It took me a full day of work (implementing + testing), and it wasn’t easy, at least not as I thought it would be. I kept telling myself that there has to be a better way.

The code wasn’t maintainable, even with the 90% code coverage I had of tests. Not by the version of me from next month or even from next week, and of course not by another dev from my team. This code will become an unmaintainable, ‘don’t touch’, legacy code as soon as I’ll push the changes to the repo and mark the task as ‘Done’.

This code is ugly.

legacy code

Oh, much better

I took a step back and tackled the problem from a different angle. I figured that my goal is pretty simple; I have a collection of values and all I have to do for the Serialize method is to:

  1. Project each message part into bits
  2. Concatenate the bits of all values
  3. Project the result into a byte array

And all I have to do for the deserialize method is to:

  1. Project the byte array into bits.
  2. Slice them according to the length of each message part
  3. Project each slice into the corresponding message part object

I quickly thought about LINQ! Isn’t this one of the scenarios that are easily solved by LINQ? I went on and explored this idea further.

I decided to use the Type-Safe Enum Pattern to represent a Bit (Bit.cs). I also used some LINQ operations from Jon Skeet’s MoreLinq library.

For the Serialize method I started by writing the following extension methods:

//Projects a byte into IEnumerable<Bit>
public static IEnumerable<Bit> ToBits(this byte @byte)
{
    for(var index = 0; index < 8; ++index, @byte >>= 1)
    {
        yield return 1 == (@byte & 1);
    }
}

//Projects IEnumerable<Bit> into a byte
public static byte ToByte(this IEnumerable<Bit> bits) =>
    bits.Reverse().Aggregate((byte)0, (currentValue, bit) => 
        (byte)((currentValue << 1 | bit) ));

//Projects a byte[] into IEnumerable<Bit>
public static IEnumerable<Bit> ToBits(this IEnumerable<byte> bytes) 
    => bytes.SelectMany(ToBits);

The following are the steps for the Serialize method:

  1. Project each value into bits, according to the BitCount property of its message-part object
    1. Project the value into bytes
    2. Project the bytes into bits
  2. Group the bits into a group of 8-bit each
  3. Project each group into a byte
  4. Project the IEnumerable of bytes into a byte array
byte[] Serialize(IEnumerable<MessagePart> messageParts)
{
    return messageParts.OrderBy(part => part.Index)
        .SelectMany(part => 
            BitConverter.GetBytes(part.Value)
            .ToBits())
        .Batch(8)
        .Select(slice => slice.ToByte())
        .ToArray();
}

(Did you notice the bug? I’ll discuss it later)

For implementing the deserialize method, I created the following extension methods:

//Projects an array of 4 bytes into an int
public static int ToInt(this byte[] bytes) => 
                            BitConverter.ToInt32(bytes, 0);

//Projects a bunch of 8-bit IEnumerables into an IEnumerable of bytes
public static IEnumerable<byte> 
    ToBytes(this IEnumerable<IEnumerable<Bit>> bits) => bits.Select(ToByte);

The following are the steps for the deserialize method:

  1. Project the byte array into IEnumerable of bits
  2. Slice the bits according to each message-part length and order
  3. Project each slice into 4 bytes (sizeof(System.Int32))
  4. Project each 4 bytes into a System.Int32
IEnumerable<MessagePart> Deserialize(IEnumerable<LayoutPart> layout, 
                                     byte[] bytes)
{
    var bits = bytes.ToBits();
    
    return layout.OrderBy(part => part.Index).Select(part =>
    {
        var slice = 
            bits
            .Take(part.BitCount)
            .Batch(8)
            .ToBytes()
            .Pad(sizeof(int), (byte)0)
            .Take(sizeof(int))
            .ToArray()
            .ToInt();

        bits = bits.Skip(part.BitCount);

        int value = BitConverter.ToInt32(slice, 0);

        return new MessagePart(part.Name, value);
    }).ToArray();
}

Looks better, Eh?

Testing the implementation

It isn’t always easy to debug LINQ operations, thus in order to debug, test and visualize my examples, I used OzCode which is an awesome debugging extension for Visual Studio. I installed the EAP (Early Access Program) edition, which includes amazing LINQ debugging capabilities, and put it to work.

This is the code according to the example above

var layout = new[]
{
    new LayoutPart("Part 0", 0, 3),
    new LayoutPart("Part 1", 1, 4),
    new LayoutPart("Part 2", 2, 11),
};

var message = new[]
{
    new MessagePart("Part 0", 0, 3, 1),
    new MessagePart("Part 1", 1, 4, 0xA),
    new MessagePart("Part 2", 2, 11, 0x1F0),
};

var serializer = new MessageSerializer();

var bytes = serializer.Serialize(message);
var messageParts = serializer.Deserialize(layout, bytes);

I used OzCode’s LINQ analyser for visualizing and tracking the LINQ operations.

Here we can see what the actual bits are, and their order in the concatenated message-parts.

snis9uf
But according to the BitCount property of Part 0, its value should be projected only to 3 bits.

Fixing the bug:

byte[] Serialize(IEnumerable<MessagePart> messageParts)
{
    return messageParts.OrderBy(part => part.Index)
        .SelectMany(part => 
            BitConverter.GetBytes(part.Value)
            .ToBits()
            .Pad(part.BitCount, Bit.Off) //Added
            .Take(part.BitCount))  //Added
        .Batch(8)
        .Select(slice => slice.ToByte())
        .ToArray();
}

I added Pad and Take to be sure I project exactly the needed count of bits.

4fbbiu8

This looks much better.

Here we can see the value of each byte:
img-1
Testing the Deserialize method, we can see the value of each message part:
gd6uv4a

Summary

Even though actions that require bitwise operations are usually considered “low-level”, I was able to use LINQ, which is considered a “high-level” API, to perform the same thing. This kind of abstraction saved me time and effort, and made my code more maintainable, readable and clean. I suggest to use abstractions whenever you can, and whenever it make sense.

What I really learnt though, is that we can use skills we acquire in one domain to solve challenges in another.
There is a saying that polyglot programmers write better code than those who specializes only in one language. I think it is yet another example of the same idea – each skill you acquire, will make you better at what you do, regardless how unrelated that skill might look like at that time.

Note: this post is published also at OzCode’s blog.