Supporting the Client Profile

August 11, 2010

This blog-post was triggered by an emphatic discussion on the NHibernate developers mailing list regarding the support for .NET’s Client Profile and more to the point, why log4net is blocking it.

The gist of it is that the Client Profile is a trimmed down version of the .NET Framework, lacking assemblies typically associated with server applications, e.g. System.Web. Unfortunately, log4net references System.Web to implement its ASP.NET TraceAppender.

Now, there are two positions one could defend. One is that log4net references System.Web, thus making it incompatible with the .NET Client Profile and subsequently preventing any application needing it from being compatible as well. Easy solution: let’s switch the logger framework. The other position is that I like log4net, and I don’t just want to give up. Or resort to runtime binding only. Which works by the way. As to the why, please keep reading.

So, how do I create an application compatible with the .NET Client Profile? Easy, just set the Target Framework to “Client Profile” in the project’s properties.

clip_image002

As soon I do this and try to link log4net, I get the following compiler error and warning:

clip_image004

Apparently, MSBuild is recursively checking all dependencies of my project to make sure no unsupported assemblies are required. That’s actually a pretty nice thing to do of MSBuild. Except for one caveat: As long as I don’t use the types located inside a referenced assembly, either by runtime or using reflection, I don’t need them on my machine. And in the case of log4net, this means that as long as I don’t configure my console application to log to the ASP.NET trace, I don’t care whether or not log4net references System.Web.

Unfortunately, there’s nothing I can do to change the compiler’s mind. The only thing I can do is go back and build my project as a regular .NET 3.5 project. But what happens when I try to start it on a machine that only has the Client Profile installed?

clip_image006

Yep, I get a wonderfully helpful error message. Fortunately, there’s an easy workaround: Just do the same thing Visual Studio does when you select the Client Profile – add the ‘sku’ attribute to the application’s config file, set it to ‘client’, and I’m golden.

clip_image008

The reason this works is that there’s not really that much of a difference between the various packages of the .NET Framework. They all have the same shim, the same mscorlib, the same assembly format. It really boils down to just one config setting telling the .NET Framework that the application can make do with the Client Profile assemblies.

Now, I’m not going to go around and advocate to just link System.Web, etc to your heart’s content and set the SKU-attribute as needed because sooner or later it will bite you. But in the case of a mulish third party component there is a workaround.

As for the practical applications. Well, if you need to be compatible with .NET Framework 2.0, you don’t need to worry because the concept of a Client Profile does not exist in the first place. Then there’s the .NET Framework 3.5 Client Profile, which is obsolete with Windows 7 since it already contains a complete .NET Framework 3.5. This leaves .NET Framework 4.0 Client Profile, which is a recommended update in Windows Updater, meaning sooner or later this is what you can expect to find on current client machines. So, in parting, I hope the log4net maintainers will get around to making their logger a first class citizen in .NET Framework 4.0.

Michael

One Response to “Supporting the Client Profile”

  1. That’s ok, in fact the just in time compiler notices the broken reference only as soon as it compiles the method that use it.

    I suppose this does not work with ngen, so you still have some issues regarding deployment.

Leave a Reply