Monthly Archives: May 2011

Extending the Func<T> delegate in .Net 3.5

Today I was working with the Func<T> delegate in my code. I was testing it at my local development machine in a .Net 4.0 console application. (Side information: I was trying to create a sort of overloaded methods which end up in a generic caching method, that has the ability to call the orginal method to get data when there is no data found in the cache.)

My data method has five arguments in the signature and I was writing the following methods:

Generic caching method:

private static TResult PerformCaching<TResult>(Func<TResult> func, string cacheKey)
{
    var cachedData = Get<object>(cacheKey); // <= check if there is data in the cache. 

    if (cachedData == null)
    {
        return func.Invoke(); // <= if not invoke the delegate. 
    }

    return (TResult)cachedData;
}

Public caching method:

public static TResult PerformCaching<TResult, T1, T2, T3, T4, T5>(Func<T1, T2, T3, T4, T5, TResult> func, T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5, string cacheKey)
{
    return PerformCaching(() => func(arg1, arg2, arg3, arg4, arg5), cacheKey);
}

 

Running this in my .Net 4.0 console application works like a charm. However when I tried to implement this in our SharePoint 2010 project, which is running .Net 3.5 it’s giving me an error in my Error console:

Using the generic type ‘System.Func<TResult>’ requires 1 type arguments

Ok, time to grab reflector and see what’s happening under the hood: I have loaded the .Net 3.5 System.Core.dll manually. (In my case Reflector is starting up with default .Net 4.0) I see the following:

SystemCoreNet35

Both Action<T> and Func<T> have a maximum support for four generic arguments in .Net 3.5.

 

Okay, let’s compare this to .Net 4.0 where my example with five arguments is working like a charm.

SystemCoreNet40

 

From .Net 4.0 on there is support for 16 generic parameters in your Func<T> delegate. Ok, very nice this support in .Net 4.0, but SharePoint 2010 is still running .Net 3.5 and probably will not be updated to .Net 4.0. How can we fix this issue in .Net 3.5?

Well, that will be very easily been fixed with one line of code Emoticon met brede lach.

In our code we add ourselves a Func<T> delegate with the five needed generic arguments like below:

public delegate TResult Func<T1, T2, T3, T4, T5, TResult>(T1 arg1, T2 arg2, T3 arg3, T4 arg4, T5 arg5); 

Now you can compile your .Net 3.5 project and it’s supporting this five arguments Func<T> delegate. Now say how easy was that?

One of the issues that interests me is the part that when I look into the .Net 4.0 System.Core DLL, the Func<T> delegate starts with Func<T1, T2, T3, T4, T5, T6, T7, T8, T9, TResult> and not with Func<T1, TResult>. I tried to found out where the other Func<T>’s have gone, and found out that these have a TypeForwardedFrom attribute like below:

[TypeForwardedFrom("System.Core, Version=3.5.0.0, Culture=Neutral, PublicKeyToken=b77a5c561934e089")]

The link gives the explanation I think very clear `Type forwarding allows you to move a type to another assembly without having to recompile applications that use the original assembly.`

Well that´s it about extending the Func<T> delegate, hope it will be helpful for you. If you have any questions or remarks please let me know in the comments.

Getting your Enterprise Library performance counters to work.

This week I have been extensively been working with Enterprise Library 5.0 .(Also called as EntLib) In most of the cases Enterprise Library works in the background and it is not always that clear about what’s happening under the hood. Well, this applied for me either this week. I’m using the Caching Application Block of Entlib and was curious about how this performed (how many items are there in the cache list, how many expirations occur, are expired items removed etc.)

First step I took was installing the EntLib instrumentation which can be installed by executing1 a .bat file which comes with the installation of Entlib.

1 Note that executing this batch file should be done with administrator privileges.

InstallInstrumentation

 

Actually I thought that this was it. All that I had to do was adding the counters in performance monitor (PerfMon) and see what happing under the hood. When I was trying to add the counters to PerfMon, I saw that the instrumentation installation has succeeded, because the counters where there.

EntLibPerformanceCounters

 

But adding the counters was not possible. After some searches on the internet I found out that you have to enable performance counters in your application before you can add them to PerfMon to see what’s going on down there.

There are two ways of enabling your application to use performance counters. One is by using the configuration tool which is shipped with EntLib, or manually update your .config file with some references to EntLib dll’s and adding a configuration section. I’ll start with the first one, which is the easiest and is doing the adding part to the .config file for you.

Updating the .config file by use of the EntLib tool:

Start the EntLib configuration tool (Can be found under: All programs => Microsoft patterns & practices => Enterprise Library 5.0 => Enterprise Library Configuration) that fits to the .Net framework you’re using in your application. In my case that will be the X86 .Net 4.0 framework.

When the configuration tool is loaded, choose File => Open, navigate to your .config file and open it. Once it is opened, choose Blocks => Add Instrumentation Settings

AddInstrumentationSettings

 

Expand the Instrumentation settings block and set performanceCountersEnabled to true. Save the settings, so they will be written to your .config file. If you restart your application after saving, and then try to add a performance counter again, you will see that your process is added to the list of instances and that you’re able to add the counters.

 

Updating the .config file manually:

I can imagine that if you’re in the situation that you don’t have the configuration tool available to adjust your .config file (Like me on the production environment) you want to insert these settings manually. Below I will show you how and where to enter these settings in your config file to make this work.

The first step will be to open your .config file in your favorite (or the available) editor.

Now we have to add two parts to the config file. First one is the reference to EntLib to make sure the compiler knows what you mean when you say that you would like to enable the performance counters.

We do that by adding a new ConfigSection. Within this configsection we add a section where we reference the EntLib 5.0 resources like below.

1 <configSections> 2 <section name="instrumentationConfiguration" 3 type="Microsoft.Practices.EnterpriseLibrary.Common.Instrumentation.Configuration.InstrumentationConfigurationSection, 4 Microsoft.Practices.EnterpriseLibrary.Common, Version=5.0.414.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" 5 requirePermission="true" /> 6 </configSections>

The second part is setting the performance counters to enabled, which can be done with below code:

1 <instrumentationConfiguration performanceCountersEnabled="true" />

That is it! Pretty easy as you know how and where to configure it.