Update: Unity with ASP.NET Web API 4 RC

Lately the Release Candidate of ASP.NET MVC 4 was released together with an updated version of the ASP.NET Web API. This blog post is an update of the previous post about a custom controller factory with Unity in Web API 4 Beta.

Changes from ASP.NET MVC 4 Beta to RC
“Independently control IHttpController selection and activation: Implement the IHttpControllerSelector to control IHttpController selection. Implement IHttpControllerActivator to control IHttpController activation. The IHttpControllerFactory abstraction has been removed.” – This is the official statement from the ASP.NET MVC site. That means that you no longer may use the IHttpControllerFactory. Instead you get fine grained control over controller selection and activation by using to separate interfaces.
The custom controller factory
For our controller factory we need to implement the IHttpControllerActivator. The interface has just a create method, used to create a certain controller:


public class UnityControllerFactory : IHttpControllerActivator
{
private readonly IUnityContainer container;
private readonly DefaultHttpControllerActivator defaultActivator;

public UnityControllerFactory(IUnityContainer container)
{
this.container = container;
defaultActivator = new DefaultHttpControllerActivator();
}

public IHttpController Create(
System.Net.Http.HttpRequestMessage request,
HttpControllerDescriptor controllerDescriptor,
Type controllerType)
{
if(container.IsRegistered(controllerType))
{
return container.Resolve(controllerType) as IHttpController;
}

return defaultActivator.Create(request,
controllerDescriptor, controllerType);
}
}

As you can see there’s a reference to the Unity container. Inside the Create method we first check, if the controller was registered with Unity or not. If it is not registered we will use a default activator to create the controller, otherwise it will be resolved using Unity.
Initializing the controller factory
The custom Http controller factory needs to be registered with the Web API pipeline in order to use it for controller creation. The HttpConfiguration in ASP.NET Web API 4 RC does not contain a service resolver any more. Instead it contains a collection of services. The collection is a specialized one and is of type DefaultServices. This collection provides methods to get services or manipulate the collection. For example it has a replace method that can be used to replace a registered type in the collection with an own implementation. We can use this method to replace the standard controller activator with our own:


var container = new UnityContainer();
container.RegisterType(typeof (Controllers.CustomerController));
var factory = new UnityControllerFactory(container);

GlobalConfiguration.Configuration.Services.Replace(
typeof (IHttpControllerActivator), factory);


That’s it. After registering your own factory this way it will be used for all requests to the Web API. There’s one disadvantage using this solution. When you create controllers with the Unity container you lose caching mechanisms that are built in the default Http controller activator. That means no controller objects are reused. You get a new instance on each API request. This disadvantage may be overcome by either configuring Unity to use Singleton objects or by implementing own caching machanisms

ORM Profiler now .NET 4.5 / Async aware

We updated our data-access profiler ORM Profiler with a new .NET 4.5 specific interceptor dll. This interceptor, which is called SD.Tools.OrmProfiler.Interceptor.NET45.dll, can be found in the main installation folder of the ORM Profiler build we uploaded this week. If you’re an ORM Profiler customer, please download the latest build from the customer area.

The .NET 4.5 interceptor intercepts calls to Async specific ADO.NET methods, and also contains all Entity Framework required classes, so there’s no need for the EF4 specific interceptor if you’re using .NET 4.5 and Entity Framework 5. Using this interceptor, any call to a *Async method will not fall back to the synchronous calls of System.Data.Common classes as the previous builds did, but will call into the Async methods of the used ADO.NET provider.

There’s more async news coming soon, namely for LLBLGen Pro v4, stay tuned

Unknown breaking change in .NET 4

Today I ran into a breaking change in .NET 4 which I couldn’t find in the documentation. It’s about binding a linq to objects query to a BindingSource’s DataSource in winforms. The code works properly in .NET 3.5, but crashes in .NET 4:

  1. _firstRelationshipsBindingSource.DataSource =
  2.                     from relationship in GuiStateSingleton.GetInstance().CurrentProject.
  3.                             GetAllRelationshipsForEntity(selectedEntity, true)
  4.                     where ((relationship.RelationshipType == EntityRelationshipType.ManyToOne) &&
  5.                             (relationship.EndVertex==selectedEntity)) ||
  6.                         ((relationship.RelationshipType == EntityRelationshipType.OneToMany) &&
  7.                             (relationship.StartVertex == selectedEntity))
  8.                     select relationship;

This binding source is bound to a simple winforms combo box. When the selection changes, I simply do:

  1. _relationshipOneViewer.ToView = (RelationshipEdge)_relationshipOneComboBox.SelectedItem;

This works, because the relationship viewer can handle ‘null’ values when there’s no selected item present. According to the query, the elements can be of type RelationshipEdge, the type of ‘relationship’ in the query.

In .NET 3.5, this works fine. If there are no elements returned by the query, this code will never hit, and even if it would, ToView would be set to null and everyone is happy. In .NET 4, it’s a different story: SelectedItem is set to a value even if there are no elements in the linq to objects query, namely aWhereEnumerableIterator instance. It works OK if the query returns values, but when the query is empty, the WhereEnumerableIterator instance is ending up as the ‘selected’ item, causing the cast to go wrong.

It’s easy to fix this of course: append a .ToList() to the query or use ‘as’ instead of the cast. The problem is that this issue is never going to pop up in previous .NET versions, so in general developers won’t think about this.

I don’t know whether this is a bug in .NET 4 or a breaking change. I can’t think of a reason why one wouldchange the .NET framework for this reason, so it looks like a bug. Either way, the only way to get rid of it is to work around it, as Microsoft isn’t shipping fixes on a regular basis.

UPDATE: When I add a .ToList(), the code works as expected, so the issue isn’t in BindingSource but in the enumerator.