Sunday, 18 November 2012

Tracking Prism EventAggregator traffic

Tracking Prism Events

It is possible to track the Prism events that are sent and received through the Prism EventAggregator,
but this is not out of the box of the Prism Framework. Usually, the developer must insert breakpoints
where the CompositePresentationEvent is published and subscribed

This is satisfactory for small scenarios, but as your solution and project(s) grow, it can become an increasingly difficult task. It is in many cases desired to see which events are published and where they are subscribed. The Prism 4.x Framework still do not support this, but luckily there is a way to achieve this. 

First off, it is required to change your Prism Events from using the class CompositePresentationEvent, to instead use a derived class presented next, CustomCompositePresentationEvent. I have chosen to display the Prism Event traffic in the Output of Visual Studio. This is done using Debug.WriteLine. It could be perhaps an alternative to log this event traffic or display it in a separate Window if you are writing a WPF application. 

The custom class CustomCompositePresentationEvent looks like this: 
using System;
using System.ComponentModel;
using System.Diagnostics;
using System.Text;
using Microsoft.Practices.Prism.Events;

namespace EventAggregation.Infrastructure
{
    
    /// <summary>
    /// Custom CompositePresentationEvent class, derived from this base class to allow the Prism Events to be displayed in the Debug Output Window. 
    /// </summary>
    public class CustomCompositePresentationEvent<TEvent> : 
    CompositePresentationEvent<TEvent> where TEvent : class 
    {

        /// <summary>
        /// Overload of the publish method of CompositePresentationEvent 
        /// </summary>
        public override void Publish(TEvent payload)
        {
            var declaringType = string.Empty; 
            var callingMethod = new StackTrace().GetFrame(1).GetMethod(); 
            if (callingMethod != null)
                declaringType = callingMethod.DeclaringType.FullName; 
            System.Diagnostics.Debug.WriteLine(string.Format(@"Publishing event {0}
            at time: {1}. Source type: {2}. Event Payload: {3}", 
            typeof(TEvent).Name,DateTime.Now, declaringType, 
            GetContentAsString(payload))); 
            base.Publish(payload);
        }

        /// <summary>Overload of the Subscribe method of  CompositePresentationEvent</summary>
        /// <remarks>
        /// For this overload to be executed, set keepSubscriberReferenceAlive to 
        /// true in the subscribe setup method on the target. 
        /// </remarks>
        public override SubscriptionToken Subscribe(Action<TEvent> action,
        ThreadOption threadOption, bool keepSubscriberReferenceAlive, 
        Predicate<TEvent> filter)
        {

            var loggingAction = new Action<TEvent>(e =>
            {
                System.Diagnostics.Debug.WriteLine(string.Format(
                "Subscribing event {0} at time: {1}. Target type: {2}", 
                typeof(TEvent).Name,
                    DateTime.Now, action.Target.GetType().Name));

                action.Invoke(e);
            });

            var subscriptionToken = base.Subscribe(loggingAction, threadOption, 
            keepSubscriberReferenceAlive, filter);
            return subscriptionToken;
        }


        private string GetContentAsString(TEvent payload)
        {
            if (payload == null)
                return string.Empty;
            else
            {
                StringBuilder sb = new StringBuilder();
                foreach (PropertyDescriptor property in 
                 TypeDescriptor.GetProperties(payload))
                {                    
                    sb.Append(string.Format("{0}={1} ", property.Name, 
                    property.GetValue(payload))); 
                }
                return sb.ToString();                 
            }
        }

    }

}

As you can see from the source code above, the methods Subscribe and Publish are overriden. These are virtual methods of the CompositePresentationEvent base class. I have tested using this derived class from CompositePresentationEvent in the EventAggregator sample, which can be downloaded in the Prism 4.1 library with source code at the following url: Download Prism 4.1 You will find the EventAggregator sample in the \QuickStarts\EventAggregation folder after you have extracted the Prism 4.1 library with source code. I have done some minor changes to this demo solution. To the project EventAggregation.Infrastructure.Desktop, I added the class I made which was just presented, CustomCompositePresentationEvent. Next up, our Prism Events must use this CustomCompositePresentation event class! This is easy to change, as shown in the Prism Event FundAddedEvent, which I changed to the following, still in the project EventAggregation.Infrastructure.Desktop:

namespace EventAggregation.Infrastructure
{
    public class FundAddedEvent : CustomCompositePresentationEvent
    {
    }
}

As you can see, the FundAddedEvent Prism Event, is now inheriting from the class CustomCompositePresentationEvent. There are no changes needed to do for the way the FundAddedEvent is published, but the Subscribe method must be changed. The boolean flag keepSubscriberReferenceAlive must be set to true. The reason is that the Subscribe override method in the CustomCompositePresentationEvent requires this, as you can see in the source code. We modify the action sent back again to the base class to continue with its Subscribe implementation. I could not make the override method to work, i.e. the method override was not called, without setting the boolean flag keepSubscribeReferenceAlive to true. The change I had to make for the subscribe method of the FundAddedEvent is in the project ModuleB.Desktop, in the class ActivityPresenter. The line 67 was changed to this:

  subscriptionToken = fundAddedEvent.Subscribe(FundAddedEventHandler,  
  ThreadOption.UIThread, true, FundOrderFilter); 
The changes required then, is to change the Prism Events to inherit from the class CompositePresentationEvent to instead inherit from (use) the class CustomCompositePresentationEvent. This custom class is basically the CompositePresentationEvent class, but we have overridden the methods Subscribe and Publish. In addition, we must set the keepSubscriberReferenceAlive boolean flag to true in our Subscribe methods. This will potentially mean that you must change to the Subscribe overload method which has this flag. Let's first see the GUI of the EventAggregation sample:







The output from the Visual Studio is the most important feature of this CustomCompositePresentationEvent class. After all, we want to be able to see which classes publish and subscribe events, and the content of the payload of these events, correct? In this sample, the output looks like the following example:

Publishing event FundOrder at time: 18.11.2012 15:31:30. Source type: ModuleA.AddFundPresenter. Event Payload: CustomerId=Customer1 TickerSymbol=FundB 
Subscribing event FundOrder at time: 18.11.2012 15:31:30. Target type: ActivityPresenter

As we can see from the output above, the event FundOrder was published by the AddFundPresenter class. The PayLoad of this Prism event was CustomerId=Customer1 and the TickerSymbol=FundB. The event FundOrder was subscribed, interestingly at the same millisecond (i.e. the publish-subscribe execution obviously performs almost instantly in the Prism framework). If you think the concept of being able to see Prism traffic is both interesting and will help you as a developer, consider taking into to use this CompositePresentationEvent class. You will have to include the changes which I listed above also, but these changes should be relatively easy to overcome in a Prism application solution. The tracking or tracing of Prism Event Traffic will help you understand the application better and catch possible errors by this more convenient debugging scenario. For security reasons, you should consider if putting a Debug.WriteLine call to output the Event Payload is safe or not. Last, I want to mention the fact that Prism Publish-Subscribe scenarios take in my test 0 ms and occur to be happening almost instantly. Of course they take some CPU cycles to execute, but if you in any case wonder how fast is really a Publish-Subscribe, it will usually be the answer - REALLY FAST. However, it is possible that if multiple classes subscribe to a given Prism Event, it might take some milliseconds to execute. I have not tested this yet. In a MVVM Scenario, it is usually the ViewModels that publish and subscribe Prism Events, usually via an ICommand implementation (DelegateCommand) that is data bound in WPF or Silverlight to a Button or similar GUI object.

Monday, 5 November 2012

User-Defined conversion sample in C#

This article will present a sample of how to implement a User Defined Conversions in C#. The article will use a typical conversion example, where temperature measured in Celsius scale (Centigrades) are converted into the Fahrenheit scale (Fahrenheits). A conversion formula is available at the following urls (Wikipedia):
User Defined Conversions are implemented in C-sharp in a similar manner as operator overloading, actually it is an overload of conversion. These conversions can be either:
  • Implicit - An object is converted into another type without a specific cast, i.e implicit cast.
  • Explicit - An object is converted into another type with a specific cast, i.e.
    explicit cast.
A class can have multiple implicit and/or explicit user defined conversions. The user defined conversions must all be methods that are marked as public and static. In addition, they must be marked as implicit or explicit to specify which cast is allowed. If a conversion is marked as explicit, converting an object into the specified type without an explicit cast will in other words not call the user defined conversion. 

To specify a User-Defined Conversion in C# which is implicit, the following signature must be used for a implicit User-Defined Conversion:
public static implicit operator TReturnType (TInputType objectToConvert) {

 .. //Implementation elided 

A User-Defined Conversion in C# which is explicit, uses the following signature: 

public static explicit operator TReturnType (TInputType objectToConvert) {

 .. //Implementation elided 

The C-sharp programmer who has experience in operator overloading will see the similarities to operator overloading. Operator overloading follows much the same signature as shown here, but without the keywords explicit or implicit. In addition, operator overloading will specify the same keyword operator, but also specify the operator to overload. User-Defined Conversion do not specify an operator to overload, but implicitly or explicitly we are overloading casting (type conversion). 
Demonstration code 
An example of how to implement User-Defined Conversion follows. In this example, a base class called Temperature is used and there are two derived classes, Celsius and Fahrenheit. Both these derived classes defines an explicit user defined conversion which will take an instance of their own type and return an instance of the converted type. This means that the Fahrenheit class will contain an explicit User-Defined Conversion which will receive a Fahrenheit instance and return a Celsius instance. In return, the Celsius class will contain an explicit User-Defined Conversion which will receive a Celsius instance and convert this into a Fahrenheit instance. In the code, the mathematical conversion between the two temperature scales is performed inside the explicit user defined conversion. This will let the programmer control the way a cast is performed and allow the client or consumer of the class to convert the type into another type through a cast and logically fill the expectation that the converted object is correctly converted or casted. 
As with operator overloading, just because C-sharp allows User Defined Conversions, does not mean that the programmer should use this functionality in the C#-language wherever this strategy might fit. User-Defined Conversions are a programming capability many C#-programmers are not aware of, and the coder which adopt this strategy might confuse his fellow programmers or quickly understand that the concepts must be explained to the other coders. But then again, just as operator overloading allows very logical and powerful expressibility in code, user defined conversion will let the programmer control the way explicit and implicit type conversions, that is - casts - are performed. If you expect the class you are writing to be casted into different types or will provide consumers or clients of your class with the benefits of simple expressibility and determined behavior, you should also add explicit user defined conversions. Implicit User-Defined Conversions are sometimes hard to see which User-Defined Conversion will be called. Therefore, if a choice is available between either implicit or explicit User-Defined Conversion, I would suggest to go for explicit. This is the most specific and clear-intentioned casting overload of the two. 
The code for the base class Temperature is shown below:     

    /// Base class for temperatures 
    /// 
    public class Temperature
    {
        protected float _value; 

        public Temperature(float temperature)
        {
            _value = temperature; 
        }

        public float Value
        {
            get { return _value; } 
        }

    }

The derived class Celsius is shown next. Note that this class defines one explicit User-Defined conversion: 
    public class Celsius : Temperature 
    {

        public Celsius(float temperature) : base(temperature)
        {
        }

        public static explicit operator Fahrenheit(Celsius temperature)
        {
            float convertedTemperature = (temperature.Value * (9.0f / 5.0f)) + 32; 
            return new Fahrenheit(convertedTemperature); 
        }

    }

The derived class Fahrenheit is shown below. This class also defines one explicit User-Defined conversion. 
    public class Fahrenheit : Temperature
    {

        public Fahrenheit(float temperature) : base(temperature)
        {
            
        }

        public static explicit operator Celsius(Fahrenheit temperature)
        {
            float convertedTemperature = (5.0f / 9.0f)*(temperature.Value - 32);
            return new Celsius(convertedTemperature); 
        }

    }

The client or consumer class is shown next:
class Program
    {

        static void Main(string[] args)
        {
            Console.WriteLine("Centigrades to Fahrenheits conversion in range [-40,40] Celsius: ");

            Celsius celsius = null;
            Fahrenheit fahrenheit = null;

            for (int i = -40; i <= 40; i++)
            {
                celsius = new Celsius(i);
                fahrenheit = (Fahrenheit)celsius;
                Console.WriteLine("{0} Centigrades is measured into {1:f1} Fahrenheits.", i, fahrenheit.Value);
            }

            Console.WriteLine("Press any key to continue ...");
            Console.ReadKey();
        }

    }

The output in the console window when running the Main method in the consumer class 
above is shown next: 
Centigrades to Fahrenheits conversion in range [-40,40] Celsius:
-40 Centigrades is measured into -40,0 Fahrenheits.
-39 Centigrades is measured into -38,2 Fahrenheits.
-38 Centigrades is measured into -36,4 Fahrenheits.
-37 Centigrades is measured into -34,6 Fahrenheits.
-36 Centigrades is measured into -32,8 Fahrenheits.
-35 Centigrades is measured into -31,0 Fahrenheits.
-34 Centigrades is measured into -29,2 Fahrenheits.
-33 Centigrades is measured into -27,4 Fahrenheits.
-32 Centigrades is measured into -25,6 Fahrenheits.
-31 Centigrades is measured into -23,8 Fahrenheits.
-30 Centigrades is measured into -22,0 Fahrenheits.
-29 Centigrades is measured into -20,2 Fahrenheits.
-28 Centigrades is measured into -18,4 Fahrenheits.
-27 Centigrades is measured into -16,6 Fahrenheits.
-26 Centigrades is measured into -14,8 Fahrenheits.
-25 Centigrades is measured into -13,0 Fahrenheits.
-24 Centigrades is measured into -11,2 Fahrenheits.
-23 Centigrades is measured into -9,4 Fahrenheits.
-22 Centigrades is measured into -7,6 Fahrenheits.
-21 Centigrades is measured into -5,8 Fahrenheits.
-20 Centigrades is measured into -4,0 Fahrenheits.
-19 Centigrades is measured into -2,2 Fahrenheits.
-18 Centigrades is measured into -0,4 Fahrenheits.
-17 Centigrades is measured into 1,4 Fahrenheits.
-16 Centigrades is measured into 3,2 Fahrenheits.
-15 Centigrades is measured into 5,0 Fahrenheits.
-14 Centigrades is measured into 6,8 Fahrenheits.
-13 Centigrades is measured into 8,6 Fahrenheits.
-12 Centigrades is measured into 10,4 Fahrenheits.
-11 Centigrades is measured into 12,2 Fahrenheits.
-10 Centigrades is measured into 14,0 Fahrenheits.
-9 Centigrades is measured into 15,8 Fahrenheits.
-8 Centigrades is measured into 17,6 Fahrenheits.
-7 Centigrades is measured into 19,4 Fahrenheits.
-6 Centigrades is measured into 21,2 Fahrenheits.
-5 Centigrades is measured into 23,0 Fahrenheits.
-4 Centigrades is measured into 24,8 Fahrenheits.
-3 Centigrades is measured into 26,6 Fahrenheits.
-2 Centigrades is measured into 28,4 Fahrenheits.
-1 Centigrades is measured into 30,2 Fahrenheits.
0 Centigrades is measured into 32,0 Fahrenheits.
1 Centigrades is measured into 33,8 Fahrenheits.
2 Centigrades is measured into 35,6 Fahrenheits.
3 Centigrades is measured into 37,4 Fahrenheits.
4 Centigrades is measured into 39,2 Fahrenheits.
5 Centigrades is measured into 41,0 Fahrenheits.
6 Centigrades is measured into 42,8 Fahrenheits.
7 Centigrades is measured into 44,6 Fahrenheits.
8 Centigrades is measured into 46,4 Fahrenheits.
9 Centigrades is measured into 48,2 Fahrenheits.
10 Centigrades is measured into 50,0 Fahrenheits.
11 Centigrades is measured into 51,8 Fahrenheits.
12 Centigrades is measured into 53,6 Fahrenheits.
13 Centigrades is measured into 55,4 Fahrenheits.
14 Centigrades is measured into 57,2 Fahrenheits.
15 Centigrades is measured into 59,0 Fahrenheits.
16 Centigrades is measured into 60,8 Fahrenheits.
17 Centigrades is measured into 62,6 Fahrenheits.
18 Centigrades is measured into 64,4 Fahrenheits.
19 Centigrades is measured into 66,2 Fahrenheits.
20 Centigrades is measured into 68,0 Fahrenheits.
21 Centigrades is measured into 69,8 Fahrenheits.
22 Centigrades is measured into 71,6 Fahrenheits.
23 Centigrades is measured into 73,4 Fahrenheits.
24 Centigrades is measured into 75,2 Fahrenheits.
25 Centigrades is measured into 77,0 Fahrenheits.
26 Centigrades is measured into 78,8 Fahrenheits.
27 Centigrades is measured into 80,6 Fahrenheits.
28 Centigrades is measured into 82,4 Fahrenheits.
29 Centigrades is measured into 84,2 Fahrenheits.
30 Centigrades is measured into 86,0 Fahrenheits.
31 Centigrades is measured into 87,8 Fahrenheits.
32 Centigrades is measured into 89,6 Fahrenheits.
33 Centigrades is measured into 91,4 Fahrenheits.
34 Centigrades is measured into 93,2 Fahrenheits.
35 Centigrades is measured into 95,0 Fahrenheits.
36 Centigrades is measured into 96,8 Fahrenheits.
37 Centigrades is measured into 98,6 Fahrenheits.
38 Centigrades is measured into 100,4 Fahrenheits.
39 Centigrades is measured into 102,2 Fahrenheits.
40 Centigrades is measured into 104,0 Fahrenheits.

Press any key to continue ...

Most Europeans are familiar with the Centigrade system, but US-English citizens use Fahrenheit scale instead for describing the temperature. The freezing point of water, 0 degrees Celsius, is 32 Fahrenheit and about -17,78 Centigrades is 0 Fahrenheit. The boiling point of water, 100 degrees Centigrades, is 212 degrees Fahrenheit. As we can see, the temperature scales grow differently and are shifted somewhat. The User-Defined conversion allows to convert the two inheriting classes of the temperature base class through explicit casts. Some, but not all programmers, believe this is a natural way of performing a conversion. Often, one can see code which actually does the same kind of functionality but does not use User-Defined conversion, i.e. a public static method which receives an instance of type TInput and returns a converted object of type TResult, but without the keywords implicit or explicit and operator. This is of course allowed, but note that this will demand that the user specifically calls this method to perform the conversion routine to get the converted instance. Instead, specifying an implicit and/or expliciting User-Defined Conversion will in many cases be less ambigious and more precise. In the end, judge yourself if User-Defined Conversions are something to use in C#. But be aware that they exist and what they can be used for. More explanation on this topic available on the MSDN page:
User Defined Conversions
If no explicit cast is performed using the cast operator (parentheses), the implicit User Defined Conversion will be called, if both a matching explicit and implicit User Defined Conversion is defined. Note that if the assignment operator = is used without a cast, the implicit conversion is used and therefore the implicit User Defined Conversion will be utilized.

Saturday, 29 September 2012

MEF and memory

For those of you that are coding in .NET today, chances are high that you are doing it in using composition through usually a container and using Inversion of Control (IoC). Many will use the Managed Extensibility Framework or MEF, for achieving IoC. MEF is not entirely a true IoC container, as the framework supports non-specific import and export of interfaces bound to implementation(s) using inheritors of ComposablePartCatalog such as AssemblyCatalog.

To download versions of MEF, visit the site http://mef.codeplex.com However, most of us will use the stable version of MEF available in .NET 4, situated in the System.ComponentModel.Composition namespace.

MEF is very easy to get started with and the concepts of importing and exporting parts are really great.
However, there is big flaw in MEF which is well known to its users and contributors, which is the way MEF handles memory. Without getting too much into detail, MEF will generally keep a reference to all parts in its container as long as the application or system is running. This results in a high and observable memory leak. To take an example, I have put together a downloadable solution at the end of this article which shows a way to avoid the memory leak. The test solution will be explained throughout this article with the most relevant parts underlined.

First off, the base of this test solution is not mine. I needed to get a sample of a WPF/MVVM/MEF/Prism solution where I could test out the concepts at home and googled for some simple demo project. I found one at the top, Prism 4 MEF application. It is available at the following URL:

Prism 4 MEF application:
http://www.codeproject.com/Articles/254120/Prism-4-MEF-Application

Code Project Open License terms:
http://www.codeproject.com/info/cpol10.aspx

I will understate that my sample is based on the solution written by Danny Siew from Wellington, New Zealand. Thanks to Danny Siew I could focus on finding a solution of the memory leak problem in MEF.

To verify that the memory leak was fixed with my solution, I downloaded the ANTS Memory Profiler from Red Gate. A trial can be downloaded at the following URL:
http://www.red-gate.com/products/dotnet-development/ants-memory-profiler/

Using the ANTS Memory Profiler, one can quickly identity the memory leak through MEF by profiling your application that is using MEF and witness that parts that are removed and is no longer used in the application are kept alive (that is, not disposed so memory resources can become available again). My main concern are the parts that are marked as CreationPolicy.NonShared. The other parts are usually the singletons, with CreationPolicy.Shared. These parts will have at most one instance and should live throughout the lifetime of the application and not become disposed before the container is disposed. It is though a huge issue that those parts that are marked as NonShared will not be dispoed before the container is dispose, because this means that the number of instances will be accumulated in memory. Clearly, not a desired behavior of MEF!

My solution is actually based upon the following discussion at the following thread on the MEF Codeplex site:
http://mef.codeplex.com/discussions/285445

Thanks to the user Palomino for this great tip:
http://www.codeplex.com/site/users/view/palomino

The strategy of Palomino is to create a CustomCatalog inheriting from the usual abstract base class ComposablePartCatalog in MEF. This class will detect when a part is requiring disposing. I have modified Palomino's code slightly, as it will deactivate the non-desired caching of the part in the CatalogExportProvider MEF uses if the part is marked as CreationPolicy.NonShared. This is how I mean the correct behavior should be. The singletons or shared parts should be disposed in the usual "MEF-way", that is when the container is disposed. The non-shared parts should be disposed when parts go out of scope for early release of resources. In no circumstances should MEF keep caching non-shared parts, as the chances for memory leak is 100%. The project manager of MEF, Glenn Block has created ExportFactory classes that are able to dispose parts on demand. This will be available in .NET 4.5 and a port has been made available at Glenn's Skydrive for download (consisting of a single DLL file) where the inherited MEF Bootstrapper can be adjusted to allow this dispose on demand. I spent some time testing out this ExportFactory class but using ANTS Memory Profiler I could not see the memory leak go away..

It is time present some code for how to avoid this memory leak problem in ANTS, since any real application or system out there using MEF today will have this huge memory leak problem and cause degraded performance and larger and larger memory footprint as the application is running.

Lets start off with this new custom catalog, for any reason of better naming, I decided to change as little of Palomino's code, so let's just call it CustomCatalog here too:



  public class CustomCatalog : ComposablePartCatalog
    {
        private readonly ComposablePartCatalog _innerCatalog;

        public CustomCatalog(ComposablePartCatalog catalog)
        {
            _innerCatalog = catalog;
        }

        public override IEnumerable<Tuple<ComposablePartDefinition, ExportDefinition>> GetExports(ImportDefinition definition)
        {
            var exports = _innerCatalog.GetExports(definition);
            return exports.Select(e => new Tuple<ComposablePartDefinition, ExportDefinition>(
                new CustomComposablePartDefinition(e.Item1), e.Item2));
        }

        public override IQueryable<ComposablePartDefinition> Parts
        {
            get
            {
                return _innerCatalog.Parts
                    .Select(p => new CustomComposablePartDefinition(p))
                    .AsQueryable();
            }
        }
    }
To explain this class in short terms, we pass in an inheritor of the abstract ComposablePartCatalog, such as AssemblyCatalog, in the constructor. Then we override the method GetExports and readonly property Parts. Instead of just returning the implementation of the passed in ComposablePartCatalog inheritor instance, a wrapping CustomComposablePartDefinition is used. This class will be presented next:
    public class CustomComposablePartDefinition : ComposablePartDefinition
    {
        private readonly ComposablePartDefinition _innerPartDefinition;

        public CustomComposablePartDefinition(ComposablePartDefinition innerPartDefinition)
        {
            _innerPartDefinition = innerPartDefinition;
        }

        public override ComposablePart CreatePart()
        {
            var innerPart = _innerPartDefinition.CreatePart();
            if (ReflectionModelServices.IsDisposalRequired(_innerPartDefinition) && 
                _innerPartDefinition.Metadata.ContainsKey(CompositionConstants.PartCreationPolicyMetadataName) && 
                (CreationPolicy)_innerPartDefinition.Metadata[CompositionConstants.PartCreationPolicyMetadataName] == CreationPolicy.NonShared)
            {
                return new NotDisposableComposablePart(innerPart);
            }
            return innerPart;
        }

        public override IEnumerable<ExportDefinition> ExportDefinitions
        {
            get { return _innerPartDefinition.ExportDefinitions; }
        }

        public override IEnumerable<ImportDefinition> ImportDefinitions
        {
            get { return _innerPartDefinition.ImportDefinitions; }
        }

        public override IDictionary<string, object> Metadata
        {
            get { return _innerPartDefinition.Metadata; }
        }

        public override string ToString()
        {
            return _innerPartDefinition.ToString();
        }
    }

The class CustomComposablePartDefinition shown above inherits from the usual ComposablePartDefinition and provides a custom functionlity for the case where the part is a NonShared part and requires disposing, which usually means the part implements IDisposable. This is the source of the memory leak, i.e. where MEF will keep its cached reference to the part in the CatalogExportProvider and stop the Garbace Collector (GC) from being able to dispose the part on a timely manner. The code for the NotDisposableComposablePart follows:
public class NotDisposableComposablePart : ComposablePart
    {

        private ComposablePart _composablePart; 

        public NotDisposableComposablePart(ComposablePart composablePart)
        {
            _composablePart = composablePart; 
        }

        public override IEnumerable<ExportDefinition> ExportDefinitions
        {
            get { return _composablePart.ExportDefinitions; }
        }

        public override object GetExportedValue(ExportDefinition definition)
        {
            return _composablePart.GetExportedValue(definition); 
        }

        public override IEnumerable<ImportDefinition> ImportDefinitions
        {
            get { return _composablePart.ImportDefinitions; }
        }

        public override void SetImport(ImportDefinition definition, IEnumerable<Export> exports)
        {
            _composablePart.SetImport(definition, exports); 
        }
    }
The NotDisposableComposablePart inherits from the base class ComposablePart. It does not implement IDisposable and will not therefore be cached by the ExportCatalogProvider of MEF. Hence, the memory leak would not occur anymore where the container keeps reference. By using the ANTS Memory Profiler I can verify this behavior. An example how of to adjust an AssemblyCatalog in the MEF Bootstrapper follows, using this CustomCatalog:
           var assemblyCatalog = new AssemblyCatalog(typeof(ItemViewModel).Assembly);
            this.AggregateCatalog.Catalogs.Add(new CustomCatalog(assemblyCatalog)); 
This wrapping of the CustomCatalog can be done not only for AssemblyCatalog and TypeCatalog and so on. Wherever a memory leak is shown in large scale in an application using MEF, the wrapping where one uses CustomCatalog is strongly recommended. The following image shows an image from the sample application, which I have adjusted some from Danny's sample on Code Project:

Here is a screenshot of the memory profiling application I use, ANTS Memory Profiler from Red Gate:

To evaluate this memory leak fix of MEF yourself, the sample solution is available for download at the following URL: Prism 4 MEF Sample with memory leak fix [Zip file, 4 MB download]


It is strange that Microsoft choose to have an instance retention policy where the disposing of parts are postponed until the disposing of the container, which is usually done when the application is exited. This actually allows a huge memory leak, especially for the NonShared parts. It is usual in say a WPF/MVVM/Prism/MEF scenario to add and remove view models and other types of instances and maintaining these parts in memory allows a great access to memory leak in a multitude of applications. If you use MEF today, do not be suprised that there are a lot of memory leaks in your managed coded application. Just because it is .NET and managed code does not mean memory leaks are not present, on the contrary side. Thanks to the great tips of Palomino, user at MEF Codeplex, and Danny Siew for providing an easy and great Prism 4 MEF starting solution. Evaluate the code. Make note that the necessary Prism and MEF DLL-s are added. In addition to .NET 4 (obviously), download Microsoft WPF Ribbon 4.0 from MSDN here:


Microsoft Ribbon 4.0 WPF I have compiled the solution in Visual Studio 2012 RC so you will find binaries in the bin folders also to start off the sample right away. Hopefully, this fix will patch MEF until MEF 2 is released. After reading a bit more about MEF 2, it seems they use ExportFactory and the early release or dispose of objects will be an opt in. It will be easier to wrap the different catalogs used with this CustomCatalog to at least try to fix the massive memory leak that MEF almost provides as default behavior. Feel free to comment this article if you have supplementary information. I have used MEF quite a lot in the last two years, but I have less deep knowledge of MEF. I wrote this article because I had to inspect if there really were workarounds of this central bug of MEF.. Happy coding!

Sunday, 16 September 2012

Testing WPF localization

WPF is a very powerful framework for rich clients, but it is not perfect. One major drawback is the support for localization. Despite localization being rather easy in framework such as ASP.NET, the process of localizing a WPF app is way too hard. The support for tools inside Visual Studio seems very poor. After googling around for suggestions, I went for the strategy of using a tool called LocBaml, which is actually a sample project inside the Windows SDK v7.1. After downloading this SDK I decided to take a short route and get an already compiled version available here: http://michaelsync.net/2010/03/01/locbaml-for-net-4-0
Reading Michael Sync blog article, a link for Locbaml.exe is available in the article linked above. I successfully used this Locbaml.exe file for testing out localization. So once we got this LocBaml tool, what is it? The Locbaml tool is a small tool for generating CSV files from a given project and generating up satellite assemblies that can be put into the subfolders of the bin\debug folder for the specified culture to localize. Locbaml got additional functionality, but this short article will not discuss them. Lets first start up with a simple GUI in WPF:
Edit the project file of the GUI and add the UICulture xml element in the .csproj file, given you implement in C#, or .vbproj for the VB developers out there.




E.g. set ui culture to english-american like this: <UICulture>en-US</UICulture> Continue, editing the AssemblyInfo.cs file and add the following:

[assembly:NeutralResourcesLanguage("en-US", UltimateResourceFallbackLocation.Satellite)]

Next up, create a new folder in the bin/debug folder. Create two folders for testing, I create here nb-NO for the Norwegian satellite assembly and the folder en-US for the English satellite asssembly file. If you compile now, it should be possible to see a satellite assembly in the bin/Debug folder and in the obj/x86 folder.


Continue with updating the xaml files of your project to have Uids The following command is to be used in the root folder of your project, use Visual Studio command prompt:

msbuild /t:updateuid TestWPFLocalization.csproj 
This will insert Uids on all the GUI elements and is another preparation step of the localization process for WPF. Sample XAML code follows showing these generated Uids:



Note the x:Uid attributes injected into each XAML element representing a visual state or control. To evaluate your progress of localizing a WPF application, see the official MSDN guide here:

http://msdn.microsoft.com/en-us/library/ms746621.aspx

The problem with the MSDN help article is - it does not work entirely. The part where Locbaml is run fails when running in the bin/Debug folder. I have instead followed the suggestions by Atul Gupta here:

http://www.infosysblogs.com/microsoft/2007/09/locbaml_to_localize_wpf_applic.html

So instead, we navigate to the obj/x86/Debug folder and first run this command:
locbaml /parse TestWPFLocalization.g.nb-NO.resources /out:TestW
PFLocalizationnb-NO.csv
Make note that it is the generate resources file in this folder we target when running the Locbaml command to generate the CSV file (comma-separated value). Sample content of the CSV file follows:

TestWPFLocalization.g.nb-NO.resources:mainwindow.baml,TextBlock_1:System.Windows.Controls.TextBlock.Text,Text,True,True,,Fornavn
TestWPFLocalization.g.nb-NO.resources:mainwindow.baml,TextBlock_1:System.Windows.Controls.Grid.Row,None,False,True,,0
TestWPFLocalization.g.nb-NO.resources:mainwindow.baml,TextBlock_1:System.Windows.Controls.Grid.Column,None,False,True,,0
TestWPFLocalization.g.nb-NO.resources:mainwindow.baml,TextBox_1:System.Windows.Controls.TextBox.$Content,Text,True,True,,
TestWPFLocalization.g.nb-NO.resources:mainwindow.baml,TextBox_1:System.Windows.Controls.Grid.Row,None,False,True,,0
TestWPFLocalization.g.nb-NO.resources:mainwindow.baml,TextBox_1:System.Windows.Controls.Grid.Column,None,False,True,,1
TestWPFLocalization.g.nb-NO.resources:mainwindow.baml,TextBlock_2:System.Windows.Controls.TextBlock.$Content,Text,True,True,,
TestWPFLocalization.g.nb-NO.resources:mainwindow.baml,TextBlock_2:System.Windows.Controls.TextBlock.Text,Text,True,True,,Etternavn
TestWPFLocalization.g.nb-NO.resources:mainwindow.baml,TextBlock_2:System.Windows.Controls.Grid.Row,None,False,True,,1
TestWPFLocalization.g.nb-NO.resources:mainwindow.baml,TextBlock_2:System.Windows.Controls.Grid.Column,None,False,True,,0
TestWPFLocalization.g.nb-NO.resources:mainwindow.baml,TextBox_2:System.Windows.Controls.TextBox.$Content,Text,True,True,,
TestWPFLocalization.g.nb-NO.resources:mainwindow.baml,TextBox_2:System.Windows.Controls.Grid.Row,None,False,True,,1
TestWPFLocalization.g.nb-NO.resources:mainwindow.baml,TextBox_2:System.Windows.Controls.Grid.Column,None,False,True,,1
TestWPFLocalization.g.nb-NO.resources:mainwindow.baml,TextBlock_3:System.Windows.Controls.TextBlock.$Content,Text,True,True,,
TestWPFLocalization.g.nb-NO.resources:mainwindow.baml,TextBlock_3:System.Windows.Controls.TextBlock.Text,Text,True,True,,Alder

The sample csv file is manually translated into Norwegian as shown above. It is is possible to edit the csv file in Excel, but I just use notepad. However, editing in Excel will perhaps be safer, as one does not delete a comma as easy when viewing the csv file inside Excel. The only text to replace in this kind of CSV file is the last parameter for the value of the localized key, for the GUI elements that should be localized. Continuing, we need to generate a new satellite assembly with this translated CSV file. Using LocBaml again, we run the following command in the obj/x86/Debug folder:

locbaml.exe /generate TestWPFLocalization.resources.dll /trans:
TestWPFLocalizationnb-NO.csv /out:.. /cul:nb-NO 
The command above takes the .csv file and generates a satellite assembly in the folder in the parent folder, that is in the obj/x86 folder. I then move this file into the nb-NO folder in the bin/Debug folder. There are now two satellite assembly files in the two folders en-US and nb-NO. Consider adding these DLL files to your project, however they will quickly go out of date. A better strategy would be to create a post build step in MSBuild to generate all these satellite assemblies dynamically. To test out the localization, you probably will want to switch the culture while running the program. Since making Locbaml work in my demo took some time, especially since the MSDN article for Localization did not present a technique that actually worked, I decided to do the short path. Add some test code in the App.xaml.cs file constructor of the App class:
   
    /// 
    /// Interaction logic for App.xaml
    /// 
    public partial class App : Application
    {
        public App()
        {
            CultureInfo ci = new CultureInfo("nb-NO");
            Thread.CurrentThread.CurrentCulture = ci;
            Thread.CurrentThread.CurrentUICulture = ci; 
        }
    }


Note that the Thread.CurrentCulture is set to an instance of CultureInfo set up to Norwegian. Running the demo app again, we can see that the satellite assembly for the Norwegian culture is picked up, and the result is displayed in the GUI

Of course, a more complete article would also discuss more background information and present code for switching language while the application is running. I decided to keep this article short, as the usage of the tool LocBaml was kind of irritating me, as the way MSDN and Microsoft explains its usage did not work. It is strange that such a versatile and powerful GUI-centric framework as WPF is so hard to use when it comes to localization. It almost seems as the WPF development team forgot to include proper support for LocBaml. Hopefully, a future version of WPF will support Localization much better without all these manual steps necessary to get started when updating.

At the same time, once this process is done, one can see that it kind of works, it is however not good that it takes this much work to get started. How about using some naming convention for Resource dictionary files, such as the one used in ASP.NET? I hope Microsoft will come with better support for localization in the next WPF version. The worst part of this strategy is that is actually some kind of "one-time localization". When the GUI is changed, one must update the Uids and then run the LocBaml commands again and copy the new assembly files to the correct subfolder in Bin\Debug. It is though not that difficult to create a new MSBuild target and add the necessary Exec xml elements in the MSBuild project file to create fresh satellite assemblies. However, the developer must translate the CSV file which does not fit well into this strategy. The end result is that the LocBaml strategy mainly lends itself to developers localizing the application after development is done and the part of localizing the application remains (i.e the application GUI will not change much for a time).

Wednesday, 5 September 2012

Basic WCF operation interception

This article will present a basic implementation of WCF operation interception. The interception is possible by implementing two interfaces, IParameterInspector and IOperationBehavior. Strictly speaking, only the interface IOperationBehavior is required for this, but this sample will present the use of IParameterInspector interface also to intercept the operation before and after the call. The following code shows how to create a sample WCF operation interception as an attribute that can be applied on a target operation in a WCF service contract.

 public class SampleOperationBehaviorAttribute : Attribute, IOperationBehavior, IParameterInspector
    {

        public void AddBindingParameters(OperationDescription operationDescription, System.ServiceModel.Channels.BindingParameterCollection bindingParameters)
        {
        }

        public void ApplyClientBehavior(OperationDescription operationDescription, System.ServiceModel.Dispatcher.ClientOperation clientOperation)
        {
            clientOperation.ParameterInspectors.Add(this); 
        }

        public void ApplyDispatchBehavior(OperationDescription operationDescription, System.ServiceModel.Dispatcher.DispatchOperation dispatchOperation)
        {
            dispatchOperation.ParameterInspectors.Add(this);
        }

        public void Validate(OperationDescription operationDescription)
        {
        }

        public void AfterCall(string operationName, object[] outputs, object returnValue, object correlationState)
        {
            Debug.WriteLine(string.Format("After call of operation {0}", operationName));
        }

        public object BeforeCall(string operationName, object[] inputs)
        {
            Debug.WriteLine(string.Format("Before call of operation {0}", operationName));
            return null;
        }

    }

As the code above shows, inheriting from Attribute class allows using the code as an attribute on the target operation. Furthermore, implementing IOperationBehavior and IParameterInspector in the same class allows easy adding the parameterinspector instance in the ApplyDispatchBehavior and ApplyClientBehavior. Finally, the last step is attributing a target operation in the service contract. The sample service will then look for example like this:
 
    [ServiceContract]
    public interface IService1
    {

        [SampleOperationBehavior]
        [OperationContract]
        string GetData(int value);
     
    }

Friday, 23 March 2012

Styling user controls in WPF with EventSetter


It is possible to style a WPF control not only with a shared style, often put into a ResourceDictionary, but also attach some behavior to the applied style, using EventSetter element in XAML. This makes it possible to quickly apply shared behavior of a WPF control in the ResourceDictionary. The ResourceDictionary with this custom Style can then be inserted into the App.xaml (application wide) file, such that all controls of that given type will have this custom style and behavior. If a style is created without a x:Key element, it is called an implicit style. This means that the user control in WPF will "inherit" this style automatically, if the control does not override the style. This again means that the Setter and EventSetter of the Style will be applied to the user control in WPF. It is also possible to set a lot of other things in a style, such as triggers, but this blog article will focus on custom code in the EventSetter element inside a WPF style.

Example - setting an EventSetter on a RadTimePicker control
The RadTimePicker is a stylish user control to set the time of the day. This user control is not part of standard WPF but created by Telerik. I worked with this control today and there was an error which actually Telerik admitted was present in their forums. If you type the text "0130" for instance, this is interpreted to "13:00", which means it is hard to type correct hours between 00:00 and 09:59. There was obviously an error when the text contains a leading zero. The suggestion from Telerik was to handle the ParseDateTimeValue event handler in the control. The problem for me was that already multiple usages of the RadTimePicker was present in the solution I was working on. I wanted to "patch" all the RadTimePicker controls with handling the ParseDateTimeHandler. The quickest way, it turned out, was to use the already added implicit style of the RadTimePicker. The style was in a resource file which was added in the App.xaml file and I just added an EventSetter element to the style element.

I will now present this technique next. First off, lets create a resource dictionary with an implicit style for the RadTimePicker element.


<ResourceDictionary x:Class="EventSetterWPF.ControlStyles"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:tc="clr-namespace:Telerik.Windows.Controls;assembly=Telerik.Windows.Controls.Input">


<Style TargetType="{x:Type tc:RadTimePicker}">
<EventSetter Event="ParseDateTimeValue" Handler="RadTimePicker_ParseDateTimeValue" />
</Style>

</ResourceDictionary>


Make note that I use x:Class here, this is a resource dictionary with a code behind. To achieve this, add a file with the same name as the resource dictionary, but with the .cs extension. E.g. the resource dictionary is called ControlStyles.xaml, then add a class called ControlStyles.xaml.cs

Add this to the class:



using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using Telerik.Windows.Controls;

namespace EventSetterWPF
{


public partial class ControlStyles : ResourceDictionary
{

public ControlStyles()
{
InitializeComponent();
}

public void RadTimePicker_ParseDateTimeValue(object sender, ParseDateTimeEventArgs e)
{
if (e.IsParsingSuccessful)
{
string originalString = e.TextToParse.Replace(":", "");
if (!string.IsNullOrEmpty(originalString) && originalString.Length == 4 && originalString.StartsWith("0"))
{
int enteredHour = -1;
int enteredMinutes = -1;
if (int.TryParse(originalString.Substring(0, 2), out enteredHour) &&
(int.TryParse(originalString.Substring(2, 2), out enteredMinutes)) &&
e.Result.HasValue)
{
DateTime originalValue = e.Result.Value;
DateTime? newValue = new DateTime(originalValue.Year, originalValue.Month, originalValue.Day,
enteredHour, enteredMinutes, 0);
e.Result = newValue;
}
}
}
}

}

}




There are two important things to consider her first. The class is made partial, which is necessary for a code behind class. The code behind is referenced by the x:Class attribute in the XAML code of the resource dictionary (ControlStyles.xaml).
Further, the resource dictionary must inherit from ResourceDictionary as its base class.

Then the EventHandler is set up in the Style of the RadTimePicker with the EventSetter:



<Style TargetType="{x:Type tc:RadTimePicker}">
<EventSetter Event="ParseDateTimeValue" Handler="RadTimePicker_ParseDateTimeValue" />
</Style>



The EventSetter element has got an attribute called Handler which points to the event handler (Callback for event) that will handle an event in the styled WPF user control. The code behind will then parse the datetime as shown in the event RadTimePicker_ParseDateTimeValue.

This is a very powerful technique in WPF. Using an implicit style for a WPF user control not only is limited to style setters, triggers or even using a control template. It is also possible to use EventSetter to have common behavior and specify the common behavior in a code behind.

The final step is just to add in the resource dictionary in the App.xaml file to make it available for all RadTimePicker controls in the application.



<Application x:Class="EventSetterWPF.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
StartupUri="TestRadTimePicker.xaml">
<Application.Resources>
<ResourceDictionary Source="ControlStyles.xaml" />
</Application.Resources>
</Application>




Understanding how we can "style" WPF user controls using EventSetter and a codebehind file opens up a whole new world of possibilites for creating advanced WPF user controls.

Monday, 5 March 2012

Speeding up Entity Framework queries with CompiledQuery

If you use Entity Framework, you may have experienced tha EF is quite slow when it comes to more complex queries against the database, because the EF query must be first compiled into SQL before it is executed to populate the EF data objects of the result set. It is possible to speed up these EFqueries, by using Compiled Queries in Entity Framework (EF). I will explain how this is done by following the MSDN page with examples of how to achieve this next, MSDN page with Compiled Queries examples

First off, not every case will benefit from a compiled query. If the query is simple or not easy parametrized, using a compiled query is not adviced. However, more often than not, you will want to compile the query first and store off that query in a static readonly variable (at least this is what is done in the examples), so that we can reuse the compiled query variable by invoking it. Let's investigate an example of how to perform such compiled query in Entity Framework.

The following code is a complete example of how to perform compiled queries:



class Program
{

static readonly Func<AdventureWorksEntities, MyParams, IQueryable<SalesOrderHeader>> s_compiledQuery =

CompiledQuery.Compile<AdventureWorksEntities, MyParams, IQueryable<SalesOrderHeader>>(
(ctx, myparams) => from sale in ctx.SalesOrderHeader
where sale.ShipDate > myparams.startDate && sale.ShipDate < myparams.endDate
&& sale.TotalDue < myparams.totalDue
select sale);

static void Main(string[] args)
{
using (AdventureWorksEntities context = new AdventureWorksEntities())
{
IQueryable<SalesOrderHeader> sales = s_compiledQuery.Invoke(context, new MyParams
{
startDate = new DateTime(2003, 3, 3),
endDate = new DateTime(2003, 3, 8),
totalDue = 700.00M
});
foreach (SalesOrderHeader sale in sales)
{
Console.WriteLine("ID: {0} Order date: {1} Total due: {2}",
sale.SalesOrderID,
sale.OrderDate,
sale.TotalDue);
}
Console.WriteLine(string.Format("Number of rows found: {0}", sales.Count()));
}

Console.WriteLine("Press any key to continue...");
Console.ReadKey();
}
}



At the top of this example code, we create a static readonly variable of type Func with the following parametres, first off AdventureWorksEntities (which is a type parameter like the rest). This is the type of the ObjectContext used in the AdventureWorks database, which I guess many of you already know about. It is possible to install the AdventureWorks on your local Sql Server 2008 (Express) R2 database, if you want to try it out. Check out this url for more information about AdventureWorks:
Download AdventureWorks sample database .

Further on, we pass in a MyParams type. It is a struct in this case (it could be a class), which we use in this example for demonstrating purposes. The overload to CompiledQuery.Compile method takes up to 16 type parameters, if you use a parameter object instead, you can provide multiple parametres. The MyParams type looks like this:




struct MyParams
{

public DateTime startDate { get; set; }

public DateTime endDate { get; set; }

public decimal totalDue { get; set; }
}




Let's have a look at the declaration of the compiled query again:


static readonly Func<AdventureWorksEntities, MyParams, IQueryable<SalesOrderHeader>> s_compiledQuery =

CompiledQuery.Compile<AdventureWorksEntities, MyParams, IQueryable<SalesOrderHeader>>(
(ctx, myparams) => from sale in ctx.SalesOrderHeader
where sale.ShipDate > myparams.startDate && sale.ShipDate < myparams.endDate
&& sale.TotalDue < myparams.totalDue
select sale);


Make a note that we use the Func type to store the compiled query. The LAST parameter is the return type of the delegate that we use, which is the right hand side of the declaration above. The return type is IQueryable of type SalesOrderHeader. This must of course match the entity framework query that is used in the right hand side. If you use an ordering expression in the EF query (orderby), the return type will be IOrderedQueryable instead. Further on, we use a lamba expression and use two variables on the left of the goes to operator => , which for some will be a bit uncommon, as most are used to x => x.MyValue and so on. It is possible to specify more than two variables also here, if you use 'index', that has a special meaning (index within the result set).. Anyways, the injection of the parameters are defined indirectly on the left hand side and then used in the EF query on the right side of the expression.

The data is fetched from the database by invoking the compiled query with the Invoke method of the Func which is assigned at the top. This will actually fetch the data. The result set is stored into a variable of type IQueryable<SalesOrderHeader> , if you want to use ordering in the EF query, use IOrderedQueryable instead, it is also possible to used grouping in the EF query of a compiled query, use IGroupedQueryable then (example not included..)



IQueryable<SalesOrderHeader> sales = s_compiledQuery.Invoke(context, new MyParams
{
startDate = new DateTime(2003, 3, 3),
endDate = new DateTime(2003, 3, 8),
totalDue = 700.00M
});



The compiled query is invoked and MyParams is specified inline here by using a constructor initializer (this is a struct which is used, however it is possible to use a class instead, if desired), the context is also passed. The invoke method of the Func will use the compiled query and invoke the query to the database and fetch the dataset using the compiled query.

If you use EF to build reports or other more complex queries, the use of a compiled query is highly recommended. It could be possible to use directly SQL, but that will mean that you will loose the support of refactoring (directly querying the database skips the overhead of translating an Entity Framework query into a sql expression).

This is therefore a highly recommended approach to performing faster Entity Framework queries against your database. Check out the MSDN page for more resources, I have not done any performance testing on this feature, but I feel it looks very promising.

Sunday, 5 February 2012

A more deterministic approach to TempData in MVC

I just read the article of Greg Shackles on custom ITempDataProvider. I will follow up his blog post with my own slight adjustments and experiences of his implementation of a persistent customized TempDataProvider, using MongoDb.

The original article is here:
MongoDb based TempData provider

The default implementation of ITempDataProvider in MVC is the class SessionStateTempDataProvider. This temp data provider relies on SessionState.
As long as the end-user applies InProc as the SessionState in web.config,
TempData should work as expected. However, as soon as a move towards SqlServer
in SessionState of web.config is selected, things will start to crash..

The following is a sample implementation of how to implement a more deterministic and stable implementation, with the aid of the MongoDb object database.

The custom ITempDataProvider looks like this:


public class CustomTempDataProvider : ITempDataProvider
{
private string _collectionName;
private string _databaseName;

public CustomTempDataProvider(string databaseName, string collectionName)
{
_collectionName = collectionName;
_databaseName = databaseName;
}

#region ITempDataProvider Members

public IDictionary LoadTempData(ControllerContext controllerContext)
{
var tempDataDictionary = new Dictionary();

using (Mongo mongo = new Mongo("mongodb://127.0.0.1:27017"))
{
mongo.Connect();
IMongoCollection collection = mongo.GetDatabase(_databaseName).
GetCollection(_collectionName);
IEnumerable tempData = collection.Find(item => item.SessionIdentifier == controllerContext.HttpContext.Request.UserHostAddress).Documents;



foreach (var tempDataItem in tempData)
{
tempDataDictionary.Add(tempDataItem.Key, tempDataItem.Value);
collection.Remove(tempDataItem);
}
}

return tempDataDictionary;
}

public void SaveTempData(ControllerContext controllerContext, IDictionary values)
{
string hostName = controllerContext.HttpContext.Request.UserHostName;
using (Mongo mongo = new Mongo())
{
mongo.Connect();

IMongoCollection collection = mongo.GetDatabase(_databaseName).
GetCollection(_collectionName);

IEnumerable oldItems = collection.Find(item =>
(item.SessionIdentifier == hostName)).Documents;

foreach (var tempDataItem in oldItems)
{
collection.Remove(tempDataItem);
}

if (values != null && values.Count > 0)
{
collection.Insert(values.Select(tempDataValue => new MongoTempData
{
SessionIdentifier = controllerContext.HttpContext.Request.UserHostAddress,
Key = tempDataValue.Key,
Value = tempDataValue.Value
}));
}
}

}

#endregion
}


Beware of the code above that the SessionIdentifier is set to the UserHostAddress of the request. Rather, you might want to inject the ASP.NET SessionId or something similar here instead to avoid multiple users accessing potentially the same data. This will both crash for the next User B since User A got to the data first (TempData removes its data after it is read). In addition User A gets to read User B TempData, which could of course include sensitive data. With that word of caution, I will leave to the read to select a good identifier for the TempData.

Next up, we create a base class for setting the TempDataProvider:


public class CustomTempDataControllerBase : Controller
{
public CustomTempDataControllerBase()
{
TempDataProvider = new CustomTempDataProvider
("test", "MongoTempData");
}
}


Our controllers do then only need to inherit from this base class (note that this base class inherits from the MVC class Controller):


public class HomeController : CustomTempDataControllerBase
{

public ActionResult Index()
{
TempData["CurrentCity"] = "Trondheim";
TempData["CurrentTemperature"] = "-7 Centigrade Windchill";
return Content("TempData updated! Read the TempData here");
}

public ActionResult ReadTempData()
{
return View();
}

}


The view ReadTempData.cshtml looks like this (Razor code):
Contents of TempData:






@foreach (var tempDataItem in TempData)
{
@tempDataItem.Key @:: @tempDataItem.Value
}


That is basically all that is too it. To start up the MongoDb on your computer, download the binaries to e.g. c:\mongodb . The binaries are available from the site:
http://www.mongodb.org/

Start the database like this:
mongod --dbpath c:\mongodb\data

Next up, get the necessary binaries from the original source of this article:
http://www.gregshackles.com/2010/07/asp-net-mvc-do-you-know-where-your-tempdata-is/comment-page-1/#comment-2491

In addition I recommend the tool MongoVUE, a GUI for viewing the data inside your collections of this object oriented database (MongoDb is not a RDBMS).

Screenshot of our sample in MongoVUE:



The source code for the custom ITempDataProvider in this article is here:
Mongo Db based custom Temp Data Provider for MVC