Tuesday, October 15, 2013

Generic Producer Consumer Class - Now on NuGet

I had the need again recently to use the producer-consumer pattern, so I got to work. I found the post I made a couple years ago, downloaded the code from it, and copied/pasted the code into my project (the only thing changing being the namespace). Not a big deal, but it takes a few minutes. I've done this process in at least two other projects, and it's annoying. I also really don't like that I've made exact duplicates of this class in multiple places. What's worse, I've made little improvements to it in each of the projects, so the codebases are beginning to diverge. If only there was a way to package it up and make it available, for free, to anyone that wanted it. And if only there was a way to maintain a historical record the different "versions" of the class.

If only.

So anyway, I created a NuGet package for the producer/consumer class. It's called RandomSkunk.ProducerConsumer. And the project is now on GitHub.

I shoulda done this a long time ago.

Saturday, May 25, 2013

Circular references between class libraries

Note: the demo project for this blog entry is on GitHub: https://github.com/bfriesen/CircularReferenceProblem.

Recently at work, we ran into a situation where we were building an internal library. Most of the library was written in C#, but some of it - complex statistical calculations - was better suited for F#. This posed a problem because the F# code needed to use some of the objects that were defined in the C# code, and the C# code needed to call the F# calculation code. Because C# and F# cannot exist in the same project, we had two projects on our hands, each of which needed to reference the other. This would cause a circular reference, and Visual Studio won't allow this to happen.

This post describes a similar situaion, and a pretty elegant solution to the problem.

The scenario

In our fake scenario, we're building a library with C# that provides a Calculator class. This class has one method, Add, that takes two Number objects. It should convert those Number objects into double values and return the result of adding those values. Now, you're going to have to suspend disbelief for a minute, but, for some reason, the developers had great difficulty in converting a Number object into a double. They determined that the best way of doing the converting was to use F#. They have created a NumberConverter class to handle this parsing.

The Number class (in the C# project):

public class Number
{
    public string Value { get; set; }
}

The NumberConverter class (in the F# project):

public class NumberConverter
{
    // Pretend really hard that this is written in F#. :)
    public double Parse(Number number)
    {
        return double.Parse(number.Value);
    }
}

The Calculator class (in the C# project):

public class Calculator
{
    private readonly NumberConverter _numberConverter;

    public Calculator()
    {
        _numberConverter = new NumberConverter();
    }

    public double Add(Number lhs, Number rhs)
    {
        return _numberConverter.Parse(lhs)
            + _numberConverter.Parse(rhs);
    }
}

The problem

.NET does not allow us to put F# code in a C# project. So we'll need to create a separate F# project. But this add a new problem: the Calculator will need to call the F# Add method of the NumberConverter class. However, the NumberConverter uses the Number class, which is defined in the C# project. This is at the heart of the circular reference problem.

Ordinarily (i.e. if this was an application, not a library), I would solve this problem by using a standard IoC container, such as Ninject. In the composition root of the application, we would wire up our dependencies (INumberConverter to NumberConverter). Then, when we needed something with dependencies, we'd ask the IoC container for it, and it would handle injecting the dependencies. But this won't work here, because we have a library, not an application. In a library, there is no composition root. So, we're stuck. Is there a way around this conumdrum? As luck would have it, there is.

The solution

To start, we'll create an interface, INumberConverter, in the C# project. Then we'll have the F# project reference the C# project. And we'll the NumberConverter class so that it inherits from INumberConverter. And we'll need to change our Calculator class too. We'll use Dependency Injection to inject an instance of INumberConverter into the Calculator.

The INumberConverter interface (in the C# project):

public interface INumberConverter
{
    double Parse(Number number);
}

The new NumberConverter class (in the F# project):

public class NumberConverter : INumberConverter
{
    // Pretend really hard that this is written in F#. :)
    public double Parse(Number number)
    {
        return double.Parse(number.Value);
    }
}

The Calculator class (in the C# project):

public class Calculator
{
    private readonly INumberConverter _numberConverter;

    public Calculator(INumberConverter numberConverter)
    {
        _numberConverter = numberConverter;
    }

    public double Add(Number lhs, Number rhs)
    {
        return _numberConverter.Parse(lhs)
            + _numberConverter.Parse(rhs);
    }
}

A new problem

This totally works, but we've eliminated the default constructor in Calculator. And that sucks. We really want that default constructor because we're making a reusable library and it is unreasonable to expect our library's consumers to have pass an inheritor of INumberConverter in to Calculator.

A new solution

We need to find a way to get that default constructor back in. What if Calculator had some magic way to get ahold of a NumberConverter? What would we do if we had that magic? We would probably have that default constructor pass the NumberConverter to the non-default constructor. Something like this:

public class Calculator
{
    private readonly INumberConverter _numberConverter;

    public Calculator(INumberConverter numberConverter)
    {
        _numberConverter = numberConverter;
    }

    public Calculator()
        : this(Magic.GetNumberConverter()) // <-- Magic!
    {
    }

    public double Add(Number lhs, Number rhs)
    {
        return _numberConverter.Parse(lhs)
            + _numberConverter.Parse(rhs);
    }
}

What if we made the GetNumberConverter method generic? Then we'd end up with Magic.Get<INumberConverter>(). And what if we renamed Magic to ServiceLocator? Well, then we'd have ServiceLocator.Get<INumberConvert>(), and we would suddenly be using the Service Locator pattern. Now, I'm not a huge fan of the Service Locator pattern. In fact, many people call it an anti-pattern. But in this case, I think it works. Especially if you declare the ServiceLocator as internal. Here's the general shape of the ServiceLocator class:

internal static class ServiceLocator
{
    public static T Get<T>()
    {
        return ??????????;
    }
}

The final piece of the puzzle

To solve the final piece of the puzzle, we're going to use Managed Extensibility Framework, or MEF. The reason why I chose MEF for this was because it's part of .NET's base class library (BCL). Because we're building a library, we don't want to force its consumers to use some third-party library. In other words, MEF is always available (at least to .NET 4.0 applications). The first thing we'll do is decorate the NumberConverter class with MEF's ExportAttribute, passing in typeof(INumberConverter. This tells MEF that we want an instance of NumberConverter to be returned when we ask MEF for a INumberConverter.

[Export(typeof(INumberConverter))] // <-- Add ExportAttribute
public class NumberConverter : INumberConverter
{
    // Pretend really hard that this is written in F#. :)
    public double Parse(Number number)
    {
        return double.Parse(number.Value);
    }
}

The final step is to tell the ServiceLocator to use MEF in order to be able to return an instance of INumberConverter. This is where MEF really shines. We can instruct MEF to scan the directory of the currently executing code for DLLs, and when it finds any, to scan the DLLs for types decorated with ExportAttribute. Without going into the details of how MEF does this, here is the final version of ServiceLocator:

internal static class ServiceLocator
{
    private static readonly CompositionContainer _container =
        new CompositionContainer(new DirectoryCatalog(@".\"));

    public static T Get<T>()
    {
        return _container.GetExportedValue<T>();
    }
}

Putting it all together

Let's create a simple console application to use the Calculator. We'll add references to both the C# project and the F# project. Then, all we need to do is instantiate a Calculator and pass in two Number objects.

static void Main()
{
    var firstNumber = new Number { Value = "123.456" };
    var secondNumber = new Number { Value = "654.321" };

    var calculator = new Calculator();
    var result = calculator.Add(firstNumber, secondNumber);

    Console.WriteLine(result);
    Console.ReadKey();
}

VoilĂ ! We have resolved the circular dependency problem, and the consumers of our library are none the wiser.

Tuesday, January 29, 2013

Flattening Polymorphism with AutoMapper

I've been working on a project that is exposed via a service layer. Trying to "do the right thing", I've created a DTO project that contains everything that is sent over the wire from the service layer (which happens to be ServiceStack). I really detest writing mapping code, so I'm using AutoMapper to take care of that for me.

I ran into an issue though - some of my entities are polymorphic. That is, I have an abstract base class and two inheritors of that base class. And I didn't want my DTOs to be polymorphic - I wanted them flat. I solved the problem by creating two methods and an interface.

Both methods require that the DTO inherit from this interface.
public interface IPolymorphicDto
{
    string Type { get; set; }
}

Here's the first method, which takes polymorphic objects and maps them to a flat DTO.

public static void CreatePolymorphicToFlatMap<
    TSourceBase,
    TSourceInheritorA,
    TSourceInheritorB,
    TDestination>()
    where TSourceInheritorA : TSourceBase
    where TSourceInheritorB : TSourceBase
{
    // Map the abstract source type to the destination DTO
    // and include the two inheritor source types.
    var mappingExpression =
        Mapper.CreateMap<TSourceBase, TDestination>()
            .Include<TSourceInheritorA, TDestination>()
            .Include<TSourceInheritorB, TDestination>();

    // Tell AutoMapper to ignore each property type that exists
    // in either inheritor but not the abstract base. (we'll
    // take care of them later)
    foreach (var name in
        typeof(TSourceInheritorA).GetProperties()
            .Where(p => p.DeclaringType
                == typeof(TSourceInheritorA))
            .Select(p => p.Name)
        .Union(typeof(TSourceInheritorB).GetProperties()
            .Where(p => p.DeclaringType
                == typeof(TSourceInheritorB))
            .Select(p => p.Name)))
    {
        mappingExpression.ForMember(name, options =>
            options.Ignore());
    }

    // Tell AutoMapper how to map the inheritor's properties.
    Mapper.CreateMap<TSourceInheritorA, TDestination>();
    Mapper.CreateMap<TSourceInheritorB, TDestination>();
}
The second method takes a flattened DTO and maps it into a polymorphic objects.
public static void CreateFlatToPolymorphicMap<
    TSource,
    TDestinationBase,
    TDestinationInheritorA,
    TDestinationInheritorB>()
    where TSource : IPolymorphicDto
    where TDestinationBase : class
    where TDestinationInheritorA : TDestinationBase, new()
    where TDestinationInheritorB : TDestinationBase, new()
{
    Mapper.CreateMap<TSource, TDestinationBase>()
        // We can't rely on AutoMapper to create an instance
        // of TDestinationBase, since it's abstract. So we
        // need to tell it how to do so.
        .ConstructUsing(source =>
        {
            // We'll use a bit of reflection to create the
            // instance.
            return (TDestinationBase)
                Activator.CreateInstance(
                    Type.GetType(source.Type));
        })
        // We also can't rely on AutoMapper to figure out
        // how to map the properties of the inheritors.
        // We're creating a TDestinationBase map here, so
        // AutoMapper won't know how to map the properties
        // that exist only in the inheritors. We'll solve
        // the problem by checking the Type property of the
        // source object (note that we put a generic constraint
        // on TSource - it must be a IPolymorphicDto). If the
        // Type property of TSource matches the full name of
        // TDestinationInheritorA, then return whatever
        // AutoMapper maps to when we tell it we're mapping to
        // TDestinationInheritorA. Otherwise, have Automapper
        // map to TDestinationInheritorB.
        .ConvertUsing(source =>
            source.Type
                == typeof(TDestinationInheritorA).FullName
            ? (TDestinationBase)
                Mapper.Map<TDestinationInheritorA>(source)
            : (TDestinationBase)
                Mapper.Map<TDestinationInheritorB>(source));

    // Finally, we need to tell AutoMapper how to map to the
    // inheritors.
    Mapper.CreateMap<TSource, TDestinationInheritorA>();
    Mapper.CreateMap<TSource, TDestinationInheritorB>();
}
So now we have our methods. Let's define some classes to map.
//Domain Objects
public class Customer
{
    private readonly List<Order> _orders = new List<Order>();

    public List<Order> Orders
    {
        get { return _orders; }
    }
}

public abstract class Order
{
    public int Id { get; set; }
}

public class OnlineOrder : Order 
{
    public string Referrer { get; set; }
}

public class MailOrder : Order
{
    public string City { get; set; }
}

//Dtos
public class CustomerDto
{
    private readonly List<OrderDto> _orders
        = new List<OrderDto>();

    public List<OrderDto> Orders
    {
        get { return _orders; }
    }
}

public class OrderDto : IPolymorphicDto
{
    public int Id { get; set; }
    public string Type { get; set; }
    public string Referrer { get; set; }
    public string City { get; set; }
}
And now we can set up our mappings.
Mapper.CreateMap<Customer, CustomerDto>();
CreatePolymorphicToFlatMap<
    Order, OnlineOrder, MailOrder, OrderDto>();
Mapper.CreateMap<CustomerDto, Customer>();
CreateFlatToPolymorphicMap<
    OrderDto, Order, OnlineOrder, MailOrder>();

// Ask AutoMapper to validate our mapping. If something is
// wrong, this will throw an exception.
Mapper.AssertConfigurationIsValid();
Finally, we can map back and forth with ease.
Customer customer = new Customer();
Order onlineOrder = new OnlineOrder
{
    Id = 1,
    Referrer = "google"
};
Order mailOrder = new MailOrder
{
    Id = 2,
    City = "Detroit"
};
customer.Orders.Add(onlineOrder);
customer.Orders.Add(mailOrder);
// customer will have two Orders: one of type OnlineOrder, with
// an Id of 1 and a Referrer of "google"; and one of type
// MailOrder, with an Id of 2 and a City of "Detroit";

var mapped = Mapper.Map<CustomerDto>(customer);    
// mapped will have two Orders: one with an Id of 1, a Type of
// OnlineOrder, a Referrer of "google", and a City with a null
// value; and one with an Id of 2, a Type of MailOrder, a
// Referrer with a null value, and a City of "Detroit".

var mappedBack = Mapper.Map<Customer>(mapped);
// mappedBack will be identical to the original customer.