Tag Archives: C#

My TransientFaultHandling utilitary classes for DocumentDB

Keluro uses extensively DocumentDB for data persistence. However, it’s extensive scaling capabilities come with a price. Indeed with your queries or your commands you may exceed the amout of request unit you are granted. In that case you will received a 429 error “Request rate too large” or a “DocumentException” if you use the .NET SDK. It is your responsability then to implement the retry policies to avoid such a failure and wait the proper amout of time before retrying.

Edit: look at the comment below. The release v1.8.0 of the .NET SDK proposes some settings options for these retry policies.

Some samples are provided by Microsoft on how to handle this 429 “Request too large error”, but they are concerning only commands, such as inserting or deleting a document, there is no sample on own to implement the retry policies for common queries. A Nuget package is also available: “Microsoft.Azure.Documents.Client.TransientFaultHandling” but even if integrating it is as quick as an eye blink, there is no logging capabilities. In my case it did not really resolve my exceeding RU problem, I even doubt that I made it work and the code is not opensource. Then, I decided to integrate the ideas from the samples in own utilitary classes on top of the DocumentDB .NET SDK.

The idea is similar to “TransientFaultHandling” package: to wrap the DocumentClient inside another class exposed only through an interface. By all accounts, it is a good thing to abstract the DocumentClient behind an interface for testability purposes. In our case this interface is named IDocumentClientWrapped.

public interface IDocumentClientWrapped : IDisposable
{
    /* Some command like methods*/
    Task DeleteDocumentAsync(Uri uri);

    Task CreateDocumentAsync(Uri uri, object obj);

    /* Some query like methods*/
    IRetryQueryable<T> CreateDocumentQuery<T>(Uri documentUri, FeedOptions feedOptions = null);

    IRetryQueryable<T> CreateDocumentQuery<T>(Uri documentCollectionUri, SqlQuerySpec sqlSpec);

    /* Copy here all other public method signature from DocumentClient but return IRetryQueryable instead of IOrderedQueryable or IQueryable */
}

Instead of returning an Queryable<T> instance as DocumentClient would do we return an IRetryQueryable<T>. This latter type, whose definition will follow, is also a wrapper on the IQueryable<T> instance returned by the DocumentDB client. However, this interface explicitely retries when the enumeration fails because of 429 request too large exception raised by the database engine, DocumentDB in our case.

public interface IRetryQueryable<T>
{
    IRetryQueryable<T> Where(Expression<Func<T, bool>> predicate);

    IDocumentQuery<T> AsDocumentQuery();

    IEnumerable<T> AsRetryEnumerable();

    IRetryQueryable<TResult> SelectMany<TResult>(Expression<Func<T, IEnumerable<TResult>>> predicate);

    IRetryQueryable<TResult> Select<TResult>(Expression<Func<T, TResult>> predicate);
}

In this interface we only expose the method extension methods that are actually supported by the “real” IQueryable<T> instance returned by DocumentDB: Select, SelectMany, Where etc. For example, at the time of the writing GroupBy is not supported. You would get an runtime exception if you used it directly on the IQueryable<T> instance returned by DocumentClient.

Now look at how we use these interfaces in the calling code.

IDocumentClientWrapped client = /* instanciation */;
IRetryQueryable<MyType> query = client.CreateDocumentQuery<MyType>(/* get usual uri using the UriFactory*/);
IEnumerable<string> = query.Where(c => c.Member1 == "SomeValue").Select(c=>c.StringMember2).AsRetryEnumerable();
/* manipulate your in memory enumeration as you wish*/

Independently of the retry policies classes and the “request too large errors”, let me emphasis that LINQ can be tricky here. Indeed, the piece of code above is completly different from this one:

IDocumentClientWrapped client = /* instanciation */;
IRetryQueryable<MyType> query = client.CreateDocumentQuery<MyType>(/* get usual uri using the UriFactory*/);
IEnumerable<string> = query.AsRetryEnumerable().Where(c => c.Member1 == "SomeValue").Select(c=>c.StringMember2);
/* manipulate your in memory enumeration as you wish*/

In this case the Where constraint is perfomed “in memory” by your .NET application server. It means that you have fetched all data from DocumentDB to your app server. If MyType contains a lot of data, then all have been transfered from DocumentDB to your application server and/or if the Where constraint filters a lot of documents you will probably have a bottleneck.

Let us get back to our problem. Now that we saw that having retry policy for a query means only calling AsRetryEnumerable() instead of AsEnumerable() let us jump to the implementation of thoses classes.

The idea is to use an IEnumerator that “retries” and use two utility method: ExecuteWithRetry,ExecuteWithRetryAsync. The former one for basic mono threaded calls while the latter is for the async/await context. Most of this code is verbose because it is only wrapping implementation. I hope it will be helpful for others.

public class DocumentClientWrapped : IDocumentClientWrapped
{
    private class RetriableEnumerable<T> : IEnumerable<T>
    {
        private readonly IEnumerable<T> _t;
        public RetriableEnumerable(IEnumerable<T> t)
        {
            _t = t;
        }

        public IEnumerator<T> GetEnumerator()
        {
            return new RetriableEnumerator<T>(ExecuteWithRetry(() => _t.GetEnumerator()));
        }

        IEnumerator IEnumerable.GetEnumerator()
        {
            return this.GetEnumerator();
        }
    }

    private class RetriableEnumerator<T> : IEnumerator<T>
    {
        private IEnumerator<T> _t;
        public RetriableEnumerator(IEnumerator<T> t)
        {
            _t = t;
        }

        public T Current
        {
            get
            {
                return ExecuteWithRetry(()=> _t.Current);
            }
        }

        object IEnumerator.Current
        {
            get
            {
                return ExecuteWithRetry(() => _t.Current);
            }
        }

        public void Dispose()
        {
            _t.Dispose();
        }

        public bool MoveNext()
        {
            return ExecuteWithRetry(() => _t.MoveNext());
        }

        public void Reset()
        {
            _t.Reset();
        }
    }

    private class RetryQueryable<T> : IRetryQueryable<T>
    {
        private readonly IQueryable<T> _queryable;
        public RetryQueryable(IQueryable<T> queryable)
        {
            _queryable = queryable;
        }

        public IDocumentQuery<T> AsDocumentQuery()
        {
            return this._queryable.AsDocumentQuery();
        }

        public IEnumerable<T> AsRetryEnumerable()
        {
            return new RetriableEnumerable<T>(this._queryable.AsEnumerable());
        }

        public IRetryQueryable<T> Where(Expression<Func<T, bool>> predicate)
        {
            var queryable = this._queryable.Where(predicate);
            return new RetryQueryable<T>(queryable);
        }

        public IRetryQueryable<TResult> SelectMany<TResult>(Expression<Func<T, IEnumerable<TResult>>> predicate)
        {
            var queryable = this._queryable.SelectMany(predicate);
            return new RetryQueryable<TResult>(queryable);
        }

        public IRetryQueryable<TResult> Select<TResult>(Expression<Func<T, TResult>> predicate)
        {
            var queryable = this._queryable.Select(predicate);
            return new RetryQueryable<TResult>(queryable);
        }
    }


    private const int MaxRetryCount = 10;

    private static async Task<V> ExecuteWithRetriesAsync<V>(Func<Task<V>> function)
    {
        TimeSpan sleepTime = TimeSpan.FromSeconds(1.0);
        int count = 0;
        while (true)
        {

            try
            {
                return await function();
            }
            catch (DocumentClientException de)
            {
                if ((int)de.StatusCode != 429)
                {
                    throw;
                }
                if (++count > MaxRetryCount)
                {
                    throw new MaxRetryException(de, count);
                }
                Trace.TraceInformation("DocumentDB async retry count: {0} - retry in: {1} - RUs: {2}", ++count, sleepTime.TotalMilliseconds, de.RequestCharge);
                sleepTime = de.RetryAfter;
            }
            catch (AggregateException ae)
            {
                if (!(ae.InnerException is DocumentClientException))
                {
                    throw;
                }

                DocumentClientException de = (DocumentClientException)ae.InnerException;
                if ((int)de.StatusCode != 429)
                {
                    throw;
                }
                if (++count > MaxRetryCount)
                {
                    throw new MaxRetryException(de, count);
                }
                Trace.TraceInformation("DocumentDB async retry count: {0} - retry in: {1} - RUs: {2}", ++count, sleepTime.TotalMilliseconds, de.RequestCharge);
                sleepTime = de.RetryAfter;
            }
            await Task.Delay(sleepTime);
        }
    }

    private static V ExecuteWithRetry<V>(Func<V> function)
    {
        TimeSpan sleepTime = TimeSpan.FromSeconds(1.0);
        int count = 0;
        while (true)
        {
            try
            {
                return function();
            }
            catch (DocumentClientException de)
            {
                if ((int)de.StatusCode != 429)
                {
                    throw;
                }
                if (++count > MaxRetryCount)
                {
                    throw new MaxRetryException(de, count);
                }
                Trace.TraceInformation("DocumentDB sync retry count: {0} - retry in: {1} - RUs: {2}", ++count, sleepTime.TotalMilliseconds, de.RequestCharge);
                sleepTime = de.RetryAfter;
            }
            catch (AggregateException ae)
            {
                if (!(ae.InnerException is DocumentClientException))
                {
                    throw;
                }

                DocumentClientException de = (DocumentClientException)ae.InnerException;
                if ((int)de.StatusCode != 429)
                {
                    throw;
                }
                if (++count > MaxRetryCount)
                {
                    throw new MaxRetryException(de, count);
                }
                Trace.TraceInformation("DocumentDB sync retry count: {0} - retry in: {1} - RUs: {2}", ++count, sleepTime.TotalMilliseconds, de.RequestCharge);
                sleepTime = de.RetryAfter;
            }
            Thread.Sleep(sleepTime);
        }
    }

    private readonly DocumentClient _client;
    public DocumentClientWrapped(string endpointUrl, string authorizationKey)
    {
        _client = new DocumentClient(new Uri(endpointUrl), authorizationKey);
    }

    public async Task CreateDocumentAsync(Uri documentCollectionUri, object obj)
    {
        ResourceResponse<Document> response = await ExecuteWithRetriesAsync(()=> _client.CreateDocumentAsync(documentCollectionUri, obj));
        LogResponse<Document>("CreateDocumentAsync", response);/* Do something with the response if you want to use it */
    }

    public async Task DeleteDocumentAsync(Uri documentUri)
    {
        ResourceResponse<Document> response = await ExecuteWithRetriesAsync( () => _client.DeleteDocumentAsync(documentUri));
        LogResponse<Document>("DeleteDocumentAsync", response); /* Do something with the response if you want to use it */
    }

    public async Task ReplaceDocumentAsync(Uri documentCollectionUri, object document)
    {
        var response = await ExecuteWithRetriesAsync(()=>  _client.ReplaceDocumentAsync(documentCollectionUri, document));
        LogResponse<Document>("ReplaceDocumentAsync", response);
    }

    public IRetryQueryable<T> CreateDocumentQuery<T>(Uri documentCollectionUri, SqlQuerySpec sqlSpec)
    {
        var queryable = _client.CreateDocumentQuery<T>(documentCollectionUri, sqlSpec);
        return new RetryQueryable<T>(queryable);
    }
}

My WPF/MVVM “must have” part 3/3 – On view model unit tests organization

One of the great advantage of the MVVM pattern is that it allows you to test the Graphic User Interface logic of the application through the view models. The latter ones are in charge of ‘presenting’ the data to your screen controls, the so-called views. For a very short introduction to MVVM, I recommend this article. This post is the last one of the series on the WPF/MVVM and it deals with the organization of the view model unit tests in a large project. I have written a blog post on how MVVM can let you test some part of your logic that you might not have thought possible before. The present blog post does not aim at presenting ‘how’ you write unit test but rather at presenting a way to organize the numerous unit tests.

When you implement unit tests for view models, you must test end-user actions. For example, you will implement test assertions for the click command on a button. Unit test should be organized so that when they fail you can easily find out the user action or presentation status of the data that you are testing. To this aim, we will use a structure of unit tests that use extensively class inheritance. Although, MSTest is not know to be the best framework for tests with inheritance, it remains the framework that I use. I do believe that one can find an even more elegant approach with other tests framework. The approach presented here is mine, I do not pretend this is the best one, it is just an example of an organization that have proven to work in large projects.

The mocking framework used is Moq. A mocking framework is not 100% mandatory for TDD. However, anytime I saw a C# project that was not using a mocking framework, then the unit tests were not really unit tests. Sometimes they were badly written and were not asserting relevant stuff and sometimes they were more or less integration tests.

Let us get back to our organization of view model tests: the basic idea is taken from the book Professional Test Driven Development in C#. I recommend it if you are unfamiliar with unit testing. It is one of the best reference that I found on the subject of TDD. It contains many relevant real life examples.

So the idea is to have a base class called Specification.

public abstract class Specification
{
    protected Specification()
    {
        Extablished_Context();
        Because_Of();
    }

    public abstract void Because_Of();

    public abstract void Extablished_Context();
}

This is the base class that all view model unit test class should inherit. I acknowledge that there are virtual calls in constructor, this not a very neat pattern. But as you probably know, C# defers from Java and C++ and the virtual call will always call the most derived class implementation of a virtual method, even in constructors.

Another thing that you must know: for each unit test execution, a new instance of the class is created, even if the tests belongs to the same test class. Consequently, we get a well test isolation without even use [TestInitialize] [TestCleanup] [ClassInitialize] attributes.

Let us go back to our Specification class, you remarked that it is abstract. To continue the organization, for each view model, you create a directory under the ViewModels directory of the test project. In this directory, create a new abstract class derived from the Specification class. This will be the base class for all test of a given view model we prefix this base class by ‘General’, e.g. for a view model called AdminViewModel, we created GeneralAdminViewModelTests class.

public abstract class GeneralAdminViewModelTests : Specification
{
    protected AdminViewModel AdminViewModel;
    protected Mock BusinessObjectFactory = new Mock();
    protected Mock IIoservice = new Mock ();
    protected Mock SettingsProvider = new Mock();
    protected Mock SubVmFactory = new Mock();

    protected Mock FileNameGeneratorViewModel = new Mock ();
    protected Mock SummaryViewModel = new Mock();
    protected Mock MainViewModel = new Mock ();
    protected Mock Bootstrapwindow = new Mock();
    protected abstract void SetupMocks();

    public override void Extablished_Context()
    {
        SetupMocks();

        AdminViewModel = new AdminViewModel(MainViewModel.Object,
                                            BusinessObjectFactory.Object,
                                            SubVmFactory.Object,
                                            IIoservice.Object,
                                            SettingsProvider.Object,
                                            Bootstrapwindow.Object);
    }
}

In this GeneralAdminViewModelTests, we instanciate the System Under Test (SUT), in this example: AdminViewModel. It is assigned to a protected field with the same name, this is the only ‘true’ implementation. The role of this GeneralAdminViewModelTest, is to pass the dependencies, that can be other view model (parent view models) or other services. The dependencies are “fresh” mock object, without any setup. The configuration of the setups depends on their usage, which will be precised in the ‘true’ derived child test class, to this aim we declare a protected abstract method SetupMocks. There is a big benefit of performing the instanciation of the SUT in one base class. Indeed, whenever you’ll add or remove a dependencies you will have just this base class implementation to change. This would have been a tedious operation if the SUT were instanciated in multiple places.

Personally, I did not managed to use one fake implementation for all tests and inject them using a IoC container. Actually, when you write unit tests you always need a different behavior of you mock depending on the test specification. For example, if you have an IoService that abstracts usage of disk I/O operation, sometimes you will want to fake a failure, an exception throwage etc. Therefore, my approach is to setups the mocks only with the behavior required for the tests. However, it is possible to factorize your mocks configuration, by using some ‘Usual Mocks’ setups.

Let us detail the true implementation of unit tests. You must separate your tests according to “existing” configurations. In my example, the AdminViewModel must deal with two situations (among others): when there are some existing data (called matters) and when there are none. That is why, under the AdminViewModelTests directory we created two files “WhenThereAreThreeMatters.cs” and “WhenThereAreNoMatter.cs”. See the resulting tree file structure in picture below.

An example of view model test organization for the 'AdminViewModel'

An example of view model test organization for the ‘AdminViewModel’

Once again, the trick is to play with inheritance. A the top of the file, we declare once again a base class. That will be the mother class of all test class in this file. In this situation, we will setup the mocks so that they fake the existence of three matters in the database.

Once the mocks are setup, we can implement the true tests class, that act as the specification of the view models. They are the most derived class (they could be marked as sealed), they are decorated with the [TestClass] attributes and the [TestMethod] attiribute for the tests. In the code listing below, there are two examples. First the WhenNothingIsDone, that will assert the following facts: when nothing is done, there are still three matters displayed, the view model is not ‘dirty’ (no changes from the end-user) and that is still possible to delete a matter. Then we have another class, that will test the behavior of our AdminViewModel, when there are ThreeExistingMatters: when we click Delete (on a matters) then, there are only two matters displayed and the view model is dirty. You may think, of others TestClass, asserting behavior of this view model under these circumstances, for example, you may Assert what is going on when the end-user clicks Save (after clicking Delete) etc.

Remark that we needed more setups for the mock in the WhenDeletingMatters implementation, so it is possible to override the the SetupMocks method to add some behavior to the mock. See examples in C# code listing below.

public abstract class AdminViewModelWithThreeExistingMatters : GeneralAdminViewModelTests
{
    public const string FirstMatter = "QSG vs Rapid Vienna";
    public const string SecondMatter = "FCN vs Juventus";
    public const string ThirdMatter = "Bordeaux vs Milan";
    protected Guid SecondMatterId;
    protected Guid FirstMatterId;

    protected override void SetupMocks()
    {
        var matter1 = MocksHelpers.GetMockMatter(FirstMatter);
        var matter2 = MocksHelpers.GetMockMatter(SecondMatter);
        var matter3 = MocksHelpers.GetMockMatter(ThirdMatter);
        SecondMatterId = matter2.Item1.Id;
        FirstMatterId = matter1.Item1.Id;
        BusinessObjectFactory.Setup(c => c.GetOrderedSharedMattersInfos()).Returns(new [] { matter1.Item2, matter2.Item2, matter3.Item2 });
        BusinessObjectFactory.Setup(c => c.GetMatterFromId(It.IsAny())).Returns((Guid guid) =>
        {
            if (guid == matter1.Item1.Id) return matter1.Item1;
            if (guid == matter2.Item1.Id) return matter2.Item1;
            if (guid == matter3.Item1.Id) return matter3.Item1;
            throw new NotImplementedException();
        });

        this.Bootstrapwindow.Setup(c => c.ShowCancelableDeleteMatterWindow()).Returns(true );
    }
}

[TestClass]
public class AdminViewModelWhenNothingIsDone : AdminViewModelWithThreeExistingMatters
{
    public override void Because_Of()
    {
    }

    [TestMethod]
    public void ThenTheSelectedMatterShouldBeTheFirstOne()
    {
        Assert.IsNotNull(AdminViewModel.SelectedMatter);
        Assert.AreEqual(FirstMatter, AdminViewModel.SelectedMatter.Name);
    }

    [TestMethod]
    public void ThenTheAvailableMattersShouldBeThree()
    {
        Assert.AreEqual(3, AdminViewModel.MatterInfos.Count());
    }

    [TestMethod]
    public void ThenTheHasChangedShouldBeFalse()
    {
        Assert.IsFalse(AdminViewModel.IsViewModelDirty);
    }

    [TestMethod]
    public void ThenTheCanClickDeleteIsSetToTrue()
    {
        Assert.IsTrue( this.AdminViewModel.CanClickDelete);
    }
}

[TestClass]
public class AdminViewModelWhenClickDelete : AdminViewModelWithThreeExistingMatters
{
    public override void Because_Of()
    {
        AdminViewModel.ClickDelete.Execute(null);
    }

    protected override void SetupMocks()
    {
        base.SetupMocks();
        this.BusinessObjectFactory.Setup(c => c.DeleteSharedMatterAsync(It .IsAny()))
            .Returns(() =>
            {
                return UsualMocks.GetSuccesfullSyncTask();
            });
        this.BusinessObjectFactory.Setup(c => c.UpsertSharedMatterAsync(It .IsAny()))
            .Returns(() =>
            {
                return UsualMocks.GetSuccesfullSyncTask();
            });
    }

    [TestMethod]
    public void ThenTheDataBaseDeleteMethodShouldBeInvokedIfClickingSave()
    {
        AdminViewModel.ClickSave.Execute( null);
        BusinessObjectFactory.Verify(c =>; c.DeleteSharedMatterAsync(It .IsAny()), Times.Once);
        Assert.IsFalse(AdminViewModel.IsViewModelDirty);
    }

    [TestMethod]
    public void ThenNumberOfAvailableMattersShouldBeSmaller()
    {
        Assert.AreEqual(2, AdminViewModel.MatterInfos.Count());
    }

    [TestMethod]
    public void HasChangedIsSetToTrue()
    {
        Assert.IsTrue(AdminViewModel.IsViewModelDirty);
    }

    [ TestMethod]
    public void ThenTheSelectedMatterShouldBeTheSecondOne()
    {
        SubVmFactory.Verify(
            c =>
            c.GetFileNameGeneratorViewModel( It.IsAny(),
                                     It.IsAny()), Times.Exactly(2));
    }

    [TestMethod]
    public void ThenTheFactoryShouldBeInvokedForAllTabs()
    {
        SubVmFactory.Verify(
            c =>
            c.GetFileNameGeneratorViewModel( It.IsAny(),
                                     It.IsAny()), Times.Exactly(2));
        SubVmFactory.Verify(
            c =>
            c.GetSummaryViewModel( It.IsAny(),
                                     It.IsAny()), Times.Exactly(2));
    }

    [TestMethod]
    public void ThenTheSelectedNameIsNotTheSecondOne()
    {
        Assert.AreEqual(SecondMatter, AdminViewModel.SelectedMatter.Name);
    }
}

Finally, one particularly helpful trick is to use the folder Namespacing conventions. Remark that a feature from Resharper enables you to enforce this convention for all files in a given folder, the current project and even the whole solution. Then our class WhenDeletingAMatter has for complete name .ViewModels.AdminViewModelTests.WhenThereAreThreeMatters.WhenDeletingAMatter. In your Resharper Test Session or VisualStudio TestExplorer, you can select ‘group by namespaces’, then you have a very neat a readable organization of your unit test as shown in the screenshot below.

When selecting the option 'GroupByNamespaces' then the readability of the test organization becomes very clear

When selecting the option ‘GroupByNamespaces’ then the readability of the test organization becomes very clear

My WPF/MVVM “must have” part 2/ 3 – No Resharper binding error in XAML code

This second post of the “WPF must have” series deals with Resharper and its ability to find binding errors in XAML.

Resharper is a well known Visual Studio plugin used by many.NET developers. It’s a great productivity tool developed by Jetbrains. Even if Resharper (abbreviated in R#) handles javascript and other languages such as VB.NET, I would say that R# is a must when it comes to C#. In addition, we will see in this post that it is also really adapted to XAML editing.

If you have followed my previous post regarding WPF and MVVM, you saw that the ViewModels (VMs), consumed by the Views (composed essentially of XAML code), are proposed by ViewModel locators, for top level VM, or by ViewModel properties. In all cases, we always manipulate the VMs through C# interfaces. This has two major advantages, the first one being the ability to work with design time data (see the first post of the series) and, the second one, to leverage unit testing (this will be the topic of the third post of the series). In addition, specifying the DataContext (i.e. the ViewModel) of a given view through an interface is particularly well adapted to R# usage in XAML.

Let us have a look at the MainWindow.xaml designer and its XAML source taken from my usual sample application DesignableMVVMSample. The vertical bar next to the XAML code is the R#’s warning/error notification zone. My recommendation is to keep the error count to zero so that the XAML file status stays always to full green (no warning, no error).

Zero error in R# warning and error bar

Zero error in R# warning and error bar

The extremely cool feature is that you will benefit from an extension of Visual Studio’s intellisense provided by R#. The interface IMainViewModel exposes a property called AvailablePersons. See in the picture below: all the properties of the ViewModel’s interface (AvailablePersons and BooksWrittenTabViewModel) are now proposed in bold, to distinguish them from the UserControl’s Dependency Properties.

R# augmented Intellisense

R# augmented Intellisense provides ViewModel members for DataBinding.

In addition, this works very well with the strongly typed translation mechanism that I presented in this previous post. Remark that all available translations are now proposed by R# and if you try to use a non translated string you will get a binding error.

Error with translations bindings

Error with translations bindings

As usual with Resharper options, you can disable them at several level: team level, solution level etc. , but more importantly, you can ignore them just once. Indeed, sometimes R# gets wrong and you may want to disable the warning/error. When you click the error you have the possibility to do this by adding the following comment in XAML. <!– ReSharper disable once Xaml.BindingWithContextNotResolved –>. Obviously, this should be exceptional, if you use this too often there is something suspicious in your code.

Let us finish by one tip. R# can detect binding error with “sub datacontext”, however,  within a DataTemplate, Resharper is not always able to recognize well the DataContext type and will raise binding errors where there are none. The trick to avoid such errors is to “force” the DataType in the DataTemplate, see the sample below.

When the DataType is specified within DataTemplate, you can continue to use R# intelisense

When the DataType is specified within DataTemplate, you can continue to use R# intelisense

When developing our product KAssistant, a legal management software fully integrated within MSOutlook, my associate Grégoire who is not a C# expert, was handling most of the work regarding the design and the views in XAML. Early binding errors detected by Resharper was of a great help and saved us a lot of precious time to focus more on the features of our product.

My WPF/MVVM “must have” part 1/ 3 – working with design time data

This is the first post of a series in three parts where I will discuss what are the “must have” of any of my WPF/MVVM projects. This one is about dealing with design time data with the framework MVVM light. The sample project of this post can be found here on my github.

When we speak of design time data in a WPF project, we refer to the data that will be visible in the Visual Studio designer. In the picture below the data displayed have no reason to be related to production or any testing dataset. They serve the only purpose of designing your app. It is important to be aware that the Visual Studio designer is extremely powerful and is able to execute some of the .NET code of your app. I have noticed also that the VS WPF designer have improved a lot with VS 2012.

Visual Studio 2013 designer

Visual Studio 2013 designer

Why having design time data is ABSOLUTELY mandatory?
First, some controls do not need data to be designed. Take a Button for example, its Content (the label) is probably static then you will not have any troubles designing it. On the contrary, if you take the DataGrid in the screenshot above, the rows are dynamic data so you won’t be able to see some lines in your VS designer unless you specify some design time data.

Now let me tell you a story. I learnt WPF because I was affected to an Excel addin project that had been started two years before. The screens had been developed using WPF but without any pattern, only (spaghetti) code behind. In addition to the fact that nothing was testable and the business logic was tightly coupled to the presentation, there was no design time data for the WPF screens. Sometimes, in order to view the effect of a single border color modification, the developer had to start the addin, connect some web services, fetch (potentially large) data etc… All of this was dramatic in term of efficiency. A complete reskin of the application was not even thinkable. Let me conclude this argumentation by saying that some data are not easily produced with a test dataset. For example, if you have a Textblock displaying a path on your hardrive. You would like to see if it is still ok if this path becomes very long. If you do not have design time data, you will have to create such a deep folder hierarchy in your drive, only to see the behavior of your TextBlock control style. This is a pity, using design time data, you may insert any string in the control in less than a second.

How do you do that in practice with an MVVM project?
We are going to take a very simple sample project (that can be found here). This application is a window with two tabs to display some information about book authors. You can select the author with a Combobox. On the first tab, there is basic information about the author while on the second tab there is the list of the books written by this author. Implementing this with MVVM: you will have three views (.xaml files): one the main window, two for the tabs.

Sample book application

In my WPF apps, all view models are specified through interfaces. Then, for the sample project, we have the three following interfaces: IMainViewModel, ISummaryTabViewModel and IBooksWrittenTabViewModel.
ISummaryTabViewModel and IBooksWrittenTabViewModel are “sub view models”. Naturally, they are exposed as member of the IMainViewModel.

public interface IMainViewModel
{
    IPerson SelectedPerson { get; set; }

    IList<IPerson> AvailablePersons { get; }

    ISummaryTabViewModel SummaryTabViewModel { get; }

    IBooksWrittenTabViewModel BooksWrittenTabViewModel { get; }
}

For each view model there are two implementations: the production implementation and the design implementation. I like to separate in another namespace the design time implementations to avoid “solution explorer visual pollution”.

Visual Studio Solution Explorer with Design ViewModels

Visual Studio Solution Explorer with Design ViewModels

We use a ViewModelLocator so that the views can find the appropriate implementation of the view model interface. Typically, the ViewModelLocator exposes a static property for the “top” rooted view model.

public class ViewModelLocator
{
   private static readonly IKernel _kernel;
   static ViewModelLocator()
   {
      _kernel = new StandardKernel();
      if (ViewModelBase.IsInDesignModeStatic)
      {
           _kernel.Bind<IMainViewModel>().To<DesignMainViewModel>();
       }
       else
       {
           _kernel.Bind<IMainViewModel>().To<MainViewModel>().InSingletonScope();
       }

   }
   public static IMainViewModel MainViewModel { get { return _kernel.Get<IMainViewModel>(); } }
}

In the sample above, I kept the IoC Ninject container (the _kernel field). You may ignore this but the ViewModelLocator is the composition root of the application, this is where an IoC Container should be used, see this post for more information.

All the magic lies in the if statement ViewModelBase.IsInDesignModeStatic which is provided by the amazing MVVM Light Framework developed by Laurent Bugnion. It will detect if the call to the ViewModelLocator comes from the Visual Studio Designer or if the application is truly running.

If you create a multi lang app with the approach detailed in one of my previous posts you can change within the if(ViewModelBase.IsInDesignModeStatic) scope the CurrentUICulture to design and see your app with any supported languages.

Now the ViewModelLocator is manipulated in the views as follows
In MainWindow.xaml

<Window x:Class="WpfApplication1.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:viewModel="clr-namespace:WpfApplication1.ViewModel" 
        xmlns:views="clr-namespace:WpfApplication1.Views"
        Title="MainWindow" Height="350" Width="525">
    <Window.DataContext>
        <Binding Path="MainViewModel" Source="{StaticResource Locator}" />
    </Window.DataContext>

In SummaryTabControl.xaml the control DataContext is bound to the SummaryTabViewModel property of the IMainViewModel.

<UserControl x:Class="WpfApplication1.Views.SummaryTabControl"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
             mc:Ignorable="d" 
             d:DesignHeight="300" d:DesignWidth="300">
    <UserControl.DataContext>
        <Binding Path="MainViewModel.SummaryTabViewModel" Source="{StaticResource Locator}"/>
    </UserControl.DataContext>

The Locator resource has been declared in the App.xaml

<Application x:Class="WpfApplication1.App" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" StartupUri="MainWindow.xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" d1p1:Ignorable="d" xmlns:d1p1="http://schemas.openxmlformats.org/markup-compatibility/2006">
  <Application.Resources>
    <vm:ViewModelLocator x:Key="Locator" d:IsDataSource="True" xmlns:vm="clr-namespace:WpfApplication1.ViewModel" />
  </Application.Resources>
</Application>

Let us have a look at the DesignMainViewModel class

public class DesignMainViewModel : IMainViewModel
{
   public static IPerson fakePerson = new Person()
   {
       Name = "Raymond Domenech",
       Age = 62,
       Books = new IBook[0]
   };

   public static IPerson fakePerson2 = new Person()
   {
       Name = "Victor Hugo", 
       Age = 45, 
       Books = new IBook[0]
   };

   public IPerson SelectedPerson
   {
       get
       {
           return fakePerson;
       }
       set
       {
           throw new NotImplementedException();
       }
   }

   public IList&lt;IPerson> AvailablePersons
   {
       get {return new []{fakePerson, fakePerson2}; }
   }

   public ISummaryTabViewModel SummaryTabViewModel
   {
       get { return new DesignSummaryTabViewModel(); }
   }

   public IBooksWrittenTabViewModel BooksWrittenTabViewModel
   {
       get { return new DesignBooksWrittenTabViewModel(); }
   }
}

and the SummaryTabViewModel class

class DesignSummaryTabViewModel : ISummaryTabViewModel
{
   public string Name { get { return "Raymond Domenech"; } }
   public int Age { get { return 62; } }
}

When implementing the “Design” view models it is important to avoid implementing any business logic. If the fake data are incoherent between the several view models design implementations that should not trouble you either. To conclude, in a real app, you will probably have to create design implementation not only for the view models but also for the objects used in data bindings (e.g. the interface IBook).

This is the end of the first part of the WPF/MVVM “must have” series. The second article will deal with the organization of the unit tests of an MVVM application.

String localization for XAML and C# using dynamically implemented interface

In this post I will describe a solution for easy localized strings management in XAML or C#. Precisely, we will use the usual recommended material for manipulating localized strings in .NET: resx files and the ResourceManager class. However, for XAML manipulation, we will add a “type layer” on top of this. We will see that having typed resources can be very useful. The “type layer” is basically an interface where string properties contain the localized strings, then in XAML or C# code the translations are accessed by using directly these properties. To avoid painful repetitions, the implementation of the interface is dynamically generated using some very simple MSIL. To conclude, we will write simple unit tests that check that the translation files (.resx) contains all the localized strings for all supported languages.

First, let us recall that it is really important that your localized strings are not dispersed in the source code of your application. Using a code snippet of the following form is a bad practice.

//don't do this
TextBox.Text = LocalizeUtil.Localize("Hello","Bonjour","Bon dia");

Indeed, it is very important that you keep grouped all the translations for a given language in one file. Then, you could rework your translations on your own or with a professional without having to grep the entire code base.

Fortunately, .NET comes with all the material you need to handle Culture-Specific resources with the ResourceManager. Say you support english (default) and french languages then you have two .resx files which contains key/value string entries. Such files are named LocalizedStrings.resx and LocalizedStrings.fr-FR.resx they may contain, among others, the entry SayHello (“Hello!” in english and “Bonjour !” in french). Finally, you only have to initialize the ResourceManager and getting the localized strings as follows.

var rem = new ResourceManager("LocalizedStrings", Assembly.GetExecutingAssembly());
Console.WriteLine(rem.GetString("SayHello"));

It is important to note that the right file (*.resx or *.fr-FR.resx) is automatically chosen using the Tread.CurrentThread.CurrentUICulture.

When manipulating XAML for the UI of your app, creating a type for the localized string is recommended. Indeed, in XAML you can bind to properties but you cannot (at least not easily) bind to methods. So the recommended method from the MSDN is to create a LocalizedStrings class whose members are the localized strings.

So we can create the LocalizedStrings class

public class LocalizedStrings
{
    private readonly ResourceManager _rem
    public LocalizedStrings(ResourceManager rem)
    {
        _rem = rem;
    }

    public string SayHello
    {
       { get {return _rem.GetString("SayHello"); }
    }

    public string SayHelloAgain
    {
       { get {return _rem.GetString("SayHelloAgain"); }
    }

    /* A lot of properties more..... */
}

While the instance is retrieved using a Singleton-like pattern (there is no reason to mock this for testing so it makes sense to use a singleton here).

public class StringLocalizer
{
    private static LocalizedStrings _localizedStrings;

    public static LocalizedStrings Strings
    {
        get
        {
            if (_localizedStrings == null)
            {
                  _localizedStrings = new LocalizedStrings(new ResourceManager("LocalizedStrings", Assembly.GetExecutingAssembly())));
             }
             return _localizedStrings;
        }
     }
}

We can use easily the LocalizedStrings in the xaml after adding the StringLocalizer has an application resource.

<!-- set the localizer has a resource -->
 <Application.Resources>
   <local:StringLocalizer xmlns:local ="clr-namespace:appNamespace"
                           x:Key="Localizer" />
 </Application.Resources>
 <!-- in the window or user control -->
 <Button DockPanel.Dock="Left"
         Command="{Binding Next}"
         ToolTip="{Binding Strings.SayHello, Source={StaticResource Localizer}}">

Obviously we can use the same class in the plain old C#

Console.WriteLine(StringLocalizer.Strings.SayHello);

Using this “type layer” is not only mandatory for XAML it is also very useful because we benefit from the static typing. Indeed, typing help us to create localized strings list that do not contain tons on unused entries. Even if this is not a matter of life or death, it is a good thing to remove unused localized strings from your dictionaries, because they going to cost you some effort or money when you will make new languages available or if you want to review the terminology used in your application. The only thing you have to do is to search for unused member of the class (the plugin Resharper does this well even in XAML).

As shown in the image below the XAML-intellisense of Resharper shows us all members of the interface which is handy to reuse localized strings.

The plugins resharper shows all properties of the LocalizedStrings class

The plugins resharper shows all properties of the LocalizedStrings class

Still there is one thing which is cumbersome, every-time you create a new entry you have to type the same logic for the property: _rem.GetString(“NameOfTheProperty”). Then, it’s time to be nerdy and find a way to do this automatically! Let us replace the LocalizedStrings class by and interface ILocalizedStrings whose implementation is dynamically generated. You can emit dynamically new type in .NET using the ILGenerator. So this is the implementation of the new StringLocalizer with some help from the .NET IL guru Olivier Guimbal.

So here it is what the interface looks like

public interface ILocalizedStrings
{
    void SetResMan(ResourceManager man);

    string SayHello{ get; }
    string SayHelloAgain{ get; }
    /* A lot of properties more..... */
}

And here is the StringLocalizer

public class StringLocalizer
{
    private static class InstanceGenerator
    {
        static readonly Dictionary<Type, ILocalizedStrings> Implementations = new Dictionary<Type, ILocalizedStrings>();
        static int _implCount = 0;

        static ModuleBuilder _moduleBuilder;
        static ModuleBuilder ModuleBuilder
        {
            get
            {
                if (_moduleBuilder != null)
                    return _moduleBuilder;
                var assemblyName = new AssemblyName { Name = "Services" };
                AssemblyBuilder assemblyBuilder = AppDomain.CurrentDomain.DefineDynamicAssembly(assemblyName, AssemblyBuilderAccess.RunAndSave);
                _moduleBuilder = assemblyBuilder.DefineDynamicModule("ServicesModule", "ServicesModule.dll");
                return _moduleBuilder;
            }
        }

        public static ILocalizedStrings CreateImplementation()
        {
            Type interfaceType = typeof(ILocalizedStrings);
            if (!interfaceType.IsInterface)
                throw new ArgumentException(interfaceType + " is not an interface type");

            ILocalizedStrings found;
            if (Implementations.TryGetValue(interfaceType, out found))
                return found;

            var module = ModuleBuilder;
            var tb = module.DefineType(interfaceType.FullName + "Impl" + (_implCount++), TypeAttributes.Public | TypeAttributes.BeforeFieldInit, typeof(object), new[] { interfaceType });

            FieldBuilder fld = tb.DefineField("_resourceManager", typeof(ResourceManager), FieldAttributes.Private);

            var setter = tb.DefineMethod("SetResMan", MethodAttributes.Public | MethodAttributes.Virtual, CallingConventions.HasThis, typeof(void), new Type[] { typeof(ResourceManager) });
            MethodInfo setMethodInfo = typeof(ILocalizedStrings).GetMethod("SetResMan");

            var setterIl = setter.GetILGenerator();
            setterIl.Emit(OpCodes.Ldarg_0);
            setterIl.Emit(OpCodes.Ldarg_1);
            setterIl.Emit(OpCodes.Stfld, fld);
            setterIl.Emit(OpCodes.Ret);

            tb.DefineMethodOverride(setter, setMethodInfo);

            var props = interfaceType.GetProperties();

            foreach (var pi in props)
            {
                if (pi.PropertyType != typeof(string))
                    throw new ArgumentException("Only string properties are supported");

                if (pi.CanWrite)
                    throw new ArgumentException("Property must be read-only: " + interfaceType + " -> " + pi.Name);

                MethodInfo methodInfo = pi.GetGetMethod();
                var mb = CreateOverride(tb, methodInfo);

                var il = mb.GetILGenerator();
                il.Emit(OpCodes.Ldarg_0);
                il.Emit(OpCodes.Ldfld, fld);
                il.Emit(OpCodes.Ldstr, pi.Name);
                il.Emit(OpCodes.Call, typeof(ResourceManager).GetMethod("GetString", new[] { typeof(string) }));
                il.Emit(OpCodes.Ret);

                PropertyBuilder pb = tb.DefineProperty(pi.Name,
                       PropertyAttributes.HasDefault,
                        CallingConventions.HasThis, methodInfo.ReturnType,
                        methodInfo.GetParameters().Select(p => p.ParameterType).ToArray());
                pb.SetGetMethod(mb);
            }

            found = (ILocalizedStrings)Activator.CreateInstance(tb.CreateType());
            Implementations.Add(interfaceType, found);
            return found;
        }

        static MethodBuilder CreateOverride(TypeBuilder tb, MethodInfo mi)
        {
            var mb = tb.DefineMethod(mi.Name,
                        MethodAttributes.Public
                        | MethodAttributes.HideBySig
                        | MethodAttributes.NewSlot
                        | MethodAttributes.Virtual
                        | MethodAttributes.Final,
                        CallingConventions.HasThis, mi.ReturnType, mi.GetParameters().Select(p => p.ParameterType).ToArray());
            tb.DefineMethodOverride(mb, mi);

            return mb;
        }
    }

    private static ILocalizedStrings _localizedStrings;

    public static ILocalizedStrings Strings
    {
        get
        {
            if (_localizedStrings == null)
            {
                _localizedStrings = (ILocalizedStrings)InstanceGenerator.CreateImplementation();
                _localizedStrings.SetResMan(new ResourceManager("LocalizedStrings", Assembly.GetExecutingAssembly())));
            }
         return _localizedStrings;
        }
    }
}
Tests are failing because some properties of the ILocalizedStrings are missing in the resx.

Tests are failing because there are some unused entries in the resx.

To conclude let us write unit tests to ensure that all properties in the interface ILocalizedStrings are defined on all .resx files and, reciprocally, to make sure that all keys in the resx files are properties of the interface. This will help us to track non translated entries and to remove useless keys in the resx dictionaries. We basically parse the .resx files to retrieve all keys and use reflexion to get all public properties of the interface. The test fail when problematic entries are discovered and printed in the test console.

[TestClass]
public class TranslationTests
{

   private TestContext _testContextInstance;
   public TestContext TestContext
   {
       get
       {
           return _testContextInstance;
       }
       set
       {
           _testContextInstance = value;
       }
   }

   private void TestPropertiesAndResxKeyAreEqual(string filePath)
   {
       XDocument xDoc = XDocument.Load(filePath);

       HashSet<string> resxKeys = new HashSet<string>(xDoc.Descendants("data").Select(c => c.Attribute("name").Value));
       HashSet<string> interfaceProp =
           new HashSet<string>(
               typeof (ILocalizedStrings).GetProperties(BindingFlags.Public | BindingFlags.Instance)
                   .Select(p => p.Name));

       bool fail = false;
       foreach (var r in resxKeys)
       {
           if (!interfaceProp.Contains(r))
           {
               _testContextInstance.WriteLine(string.Format("The key {0} exists in resx but not in interface", r));
               fail = true;

           }
       }

       foreach (var property in interfaceProp)
       {
           if (!resxKeys.Contains(property))
           {
               _testContextInstance.WriteLine(string.Format("The key {0} exists in interface but not in resx", property));
               fail = true;
           }
       }
       if (fail)
       {
           Assert.Fail();
       }

   }

   [TestMethod]
   public void TestEnglishResx()
   {
       const string path = @"../../../MyApp/LocalizedStrings.resx";
       TestPropertiesAndResxKeyAreEqual(path);
   }

   [TestMethod]
   public void TestFrenchResx()
   {
       const string path = @"../../../MyApp/LocalizedStrings.fr-FR.resx";
       TestPropertiesAndResxKeyAreEqual(path);
   }
}