Back in 2007 I wrote a post about WinMerge support for TFS in Visual Studio. It turned out to be the most hit post on my blog ever since. I have just updated the post with some reg files that add the same support for VS2010 for both x86 and x64 platforms.
In Part 1, I described the code used to leverage ServiceHostFactory to create WCF service instances with dependency injection via Unity. Using a custom ServiceHostFactory is a really easy way to get dependency injection in WCF but comes with two drawbacks. The standard Unity configuration section name (“unity”) must be used and named Unity containers are not supported. Most applications will work within these constraints.
Using a configuration based service behavior is the answer to situations where these constraints are a problem. The UnityServiceElement class is used to define the configuration support for the UnityServiceBehavior. As outlined in the last post, the UnityServiceBehavior class is used to assign a custom instance provider to each endpoint in the service. The instance provider is used to resolve a service instance from a Unity container.
There are a few ways that Unity can be used to construct WCF service instances. The options are poor mans injection, service host factories and configured behaviours.
The poor mans injection option is to create a unity container within the constructor of the service type and resolve dependencies from within the service instance. This is not elegant and couples the IOC implementation (Unity in this case) to the service.
The second option is to create a custom service host factory. This option allows a service type to be created with constructor dependencies rather than a default constructor. It uses the mark-up in svc files to identify the custom factory to be used rather than the default one. The 4.0 framework also supports this configuration via web.config as svc files are no longer required.
I recently posted about how to resolve appSetting values for parameter injection in Unity. After seeing the news yesterday (here and here) of Unity 2 being released with EntLib 5, I decided to revisit this functionality to adopt the latest and greatest.
There are some issues with adopting Unity 2 in the short-term. Unity 2 isn’t actually released by itself (as noted in a comment by Grigori Melnik), although it is bundled with EntLib 5. This means that there is no documentation for the changes found in the new version of Unity. The EntLib documentation for Unity simply says that “Content for this topic is not yet available”.
Given these constraints, I have a working solution after several hours of surfing Reflector.
I’m writing a system that exposes several services. Each service is created using Unity and has many dependency slices including business layers, data access layers, caching, logging and exception management.
As I was writing the exception management slice, the code started to get incredibly duplicated. Each method in the class began to look like this:
I wasted a lot of time this afternoon trying to get some Unity configuration to work.
One of the issues I had was that I wanted to inject a concrete type that didn’t have an interface. This turned about to be simple as Unity natively supports it. You just don’t need to define a mapTo attribute on the type element. The issue that hit me was that Unity was not invoking the constructor that I was expecting. My type that has the following constructors:
I was reminded this morning of an email that I sent to the junior developers on my team when they joined us. It is an overview of some of the development practices, patterns and products that they would get exposed to on our project. I have included it here as a reference collection for others.
Principles and Patterns
These are things that I often use and are still learning to use.
I’ve been working with Unity a bit in an enterprise level system and I have been trying to separate objects of different concerns as much as possible. One requirement hit me today where I have a dependency that is resolved from a Unity container. I created a cache dependency layer to go around it, but needed to provide a configuration value to the cache wrapper.
To demonstrate this scenario, consider the following example:
I’ve been playing with the MSF over the last couple of years. For too long I have been dabbling in a services based project that synchronises data between a set of clients. The system has been through several designs starting with hand-crafted change tracking which was really tricky. The next version used MSF on the client manage this process. This didn’t have the best result as there was no central replica for the data held by the service. The third design used a proxy provider so that central metadata information was held by the service. The fourth and latest design completely pushes MSF into the service.
The latest design allows clients to simply work with services and not have to have any understanding of MSF. There are a few hurdles with this design however. The provider implementation on the server needs to implement a preview sync so it can tell the client what changes needs to happen without doing them at that time. When a change does happens, the client will only action a single change at a time each of which must operate within a sync session in the service. This means that the sync provider also needs to work with a filtered sync session.
I’ve been developing a windows NT service for the last week and I hit an interesting issue today. The configuration for the service contains a relative path which is used in the construction of a class. When this constructor is called, the code checks if the directory exists and creates it if it doesn’t.
The service in question logged errors indicating that there were insufficient privileges for creating the directory. This told me two things. Firstly the directory didn’t exist and secondly there is a permissions problem. I verified that the directory was created by the installer so that means that there is an issue with relative paths.
I quickly realised that the current working directory of a Windows service is probably not the path of the service assembly. Most likely the current directory for a Windows service is C:\Windows\System32. This meant that any work with relative paths was likely to cause grief.