An extension method that will be making its way into the Generic Extension Methods library is one I want to share tonight.  It’s for projecting an action N times.  Why such a method doesn’t already exist baffles me!

        public static T Project<T>(this T projected, int n, Action<T> action)

        {

            for (int i = 0; i < n; ++i) action(projected);

            return projected;

        }

Usage could not be simpler, any object can be projected to the specified action any number of times.

        public static int Method()

        {

            var value = 1;

            return value.Project(10, i => i*=i);

        }

 

The projection in this case yields 10^10 as the answer.  Overly simplistic example, but makes the point succinctly.

INTRODUCTION: Previously, I wrote about the MVC design pattern.  That article focused on the mechanics of the pattern more than a realistic implementation.  In this article we’ll look at a full MVC application, starting with the Model, the Controller and finally the Views as implemented in a Windows 10 Universal Application.

THE MODEL: For this application we’ll use a fairly complex Person class that has normal CRUD properties as well as some data-centric properties such as calculating age from the Date of Birth property.  This will give you a good idea of the kind of classes you can make for serialization using your preferred format (SOAP, JSON, Binary, etc).

EXAMPLE 1 – THE PERSON CLASS

using System;
using System.ComponentModel;
using System.Runtime.CompilerServices;
using System.Runtime.Serialization;

namespace SharpNinja.Models.BlogEntities
{
    [DataContract]
    public class Person : INotifyPropertyChanged
    {
        private string _firstName;
        private string _lastName;
        private DateTime _dateOfBirth = DateTime.Today;

        public Person(string firstName, string lastName)
        {
            FirstName = firstName;
            LastName = lastName;
        }

        [DataMember]
        public string FirstName
        {
            get { return _firstName; }
            set
            {
                if (value == _firstName) return;
                _firstName = value;
                OnPropertyChanged();
            }
        }

        public string Name => $"{FirstName} {LastName}";

        [DataMember]
        public string LastName
        {
            get { return _lastName; }
            set
            {
                if (value == _lastName) return;
                _lastName = value;
                OnPropertyChanged();
            }
        }

        [DataMember]
        public DateTime DateOfBirth
        {
            get { return _dateOfBirth; }
            set
            {
                if (value.Equals(_dateOfBirth)) return;
                _dateOfBirth = value;
                OnPropertyChanged();
                OnPropertyChanged(nameof(Age));
                OnPropertyChanged(nameof(IsChild));
            }
        }

        public int Age => (DateTime.Today - DateOfBirth).Days / 365;

        public bool IsChild => Age < 18;

        public event PropertyChangedEventHandler PropertyChanged;

        protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }
    }
}

The Person class has a lot of nifty features. It implements INotifyPropertyChanged so that views that are databinding capable are able to bind to the values of the Person. Another feature is that it’s marked as a DataContract which allows it to be easily serialized. The properties representing the serializable content are also decorated with the DataMember attribute.

Just a quick note… See that method invocation of PropertyChanged? That’s the correct way to call an event using Null Propagation.

VIEWS PART 1: Our Person Model now needs to be interacted with in some way. There are two main use cases for our application: get a list of Person instances and editing a Person. For this tutorial we will focus on getting the list of Person instances by create a simple search engine for Game of Thrones characters.

The view for the search engine will define a list of Person objects, an event for telling the Controller that a search is required, and a callback method for the Controller to let the View know that new results are ready.

EXAMPLE 2

using System;
using System.Collections.ObjectModel;
using SharpNinja.Models.BlogEntities;
using SharpNinja.Utilities.MvcBasics;

namespace SharpNinja.UI.Windows10Sample.Views
{
    public interface IPersonsListView : IView
    {
        ObservableCollection<Person> PersonsList { get; set; }

        event EventHandler<string> FindPersons;

        void BindPersonsList();
    }
}

That’s all that’s necessary to define the View, and that’s all that’s necessary to implement the Controller.

BTW, all of the source code for this article (and the next one) is located on GitHub. You will see some code there that’s not 100% pertinent to this article.

THE CONTROLLER: The Controller is the heart of the application. It is responsible for persisting and retrieving Models from the data store, for enforcing the rules of the application, and for providing non-UI oriented logic. In our app, the Controller will act as the search engine, accepting a partial match string as a parameter for the FindPersons event of the IPersonsListView.

using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using SharpNinja.Models.BlogEntities;
using SharpNinja.UI.Windows10Sample.Views;
using SharpNinja.Utilities.MvcBasics;

namespace SharpNinja.UI.Windows10Sample.Controllers
{
    public class PersonsController : IController
    {
        private List<Person> _fakePersonsDatabase;

        public PersonsController()
        {
            _fakePersonsDatabase = new List<Person>();

            _fakePersonsDatabase.Add(new Person("John", "Snow") { DateOfBirth = new DateTime(1995, 2, 28) });
            _fakePersonsDatabase.Add(new Person("Ned", "Stark") { DateOfBirth = new DateTime(1971, 1, 15) });
            _fakePersonsDatabase.Add(new Person("Stannis", "Barathian") { DateOfBirth = new DateTime(1952, 12, 8) });
            _fakePersonsDatabase.Add(new Person("Aria", "Stark") { DateOfBirth = new DateTime(2003, 7, 10) });
        }

        #region IDisposable
        protected bool _isDisposed = false;
        public void Dispose()
        {
            if (!_isDisposed)
            {
                // Dispose of resources

                _isDisposed = true;
            }
        }
        #endregion

        #region Views
        private readonly List<IView> _views = new List<IView>();
        private IPersonsListView _personsListView = null;

        protected IPersonsListView PersonsListView
        {
            get
            {
                return _personsListView ??
                       (_personsListView = _views.FirstOrDefault(x => x is IPersonsListView) as IPersonsListView);
            }
        }
        #endregion

        public void Initialize(ICollection<IView> views)
        {
            foreach (var view in views)
            {
                if (view is IPersonsListView &amp;&amp; !_views.Any(x => x is IPersonsListView))
                {
                    _views.Add(view);

                    PersonsListView.FindPersons -= PersonsListViewOnFindPersons;
                    PersonsListView.FindPersons += PersonsListViewOnFindPersons;
                }
            }
        }

        private void PersonsListViewOnFindPersons(object sender, string s)
        {
            if (PersonsListView != null)
            {
                var search = s.ToLower();
                var results =
                    _fakePersonsDatabase.Where(
                        x => x.FirstName.ToLower().Contains(search) || x.LastName.ToLower().Contains(search)).ToList();

                if (results.Count > 0)
                {
                    PersonsListView.PersonsList = new ObservableCollection<Person>(results);

                    PersonsListView.BindPersonsList();
                    PersonsListView.SetStatus($"Found {results.Count} persons matching {s}", false);
                }
                else
                {
                    PersonsListView.SetStatus($"No results found for {s}.", true);
                }
            }
        }
    }
}

There’s a lot going on here, so let’s start at the top. Our application implements a fake datastore of GoT characters. This is not typical of a real app, but I didn’t want to introduce database code into this first example.

Next, you will see a property named PersonsListView. This property makes it possible to use a strongly typed instance of the View while only having to do the type checking once.

Our compulsary Initialize method adds IView instances to the controller. It knows about the events exposed in the View and appropriately registers to those events.

Finally, our event handler method does the searching of the fake datastore and places the data in the View’s PersonsList and invokes the View’s BindPersonsList call-back method.

STOPPING POINT:  That’s enough for this article.  The next article will bring it all together into a Windows 10 Universal App.  See you then!

INTRODUCTION: Let’s take a poll… As a developer, what keeps you on your toes, yet mind-numbingly bored at the same time? For me, it’s null reference checking. I know I’m not alone and that it’s such a pervasive problem that Microsoft decided to do something about it. Welcome to the enlightened world of Null Propagation.

Null Propagation is a new feature in C# 6 that allows you to chain together nullable operations into a single chain that short-circuits on the first null reference, without worrying about having to check the whole chain for null references.

This is one of the most impressive solutions to the mess that arises from continuously nested null reference checks. Let’s look at some code.

EXAMPLE 1

string oops = null;
oops = MethodThatMayReturnNull();
if(oops != null)
{
    // Assume an extension method on String.  **
    oops.MethodThatProcessesOopsThatMayReturnNull(someOtherValue);

    if(oops != null)
    {
        // You get the picture...
    }
}

** (see: This Article)

What a mess!

EXAMPLE 2

string oops = MethodThatMayReturnNull()?.MethodThatProcessesOopsThatMayReturnNull(someOtherValue); // Just keep chaining!

Where’s the Null Reference checks? See that ? between methods? It means that the second method will be called only if the first method does NOT return a null value. If it does return a null value, then the call chain is broken and oops contains a null. That’s when you test for null: when it actually means something semantically to the application.

One of the most common usages of Null Propagation is calling events. Turn 4 lines of code into 1!

// Old way
if(eventDeclaration != null)
{
    eventDeclaration(this, EventArgs.Empty);
}

// The Null Propagation Way
eventDeclaration?.Invoke(this, EventArgs.Empty);

CONCLUSION: I love C# 6! This is a game changer. You write better code that is both easier to read, and more reliable (admit it, how many times have you neglected that Null Reference Check because you were certain you’d never have a Null Reference. How’d that work for ya?) Now, with Null Propagation, there’s no excuse for writing code that doesn’t use proper Null Reference checking because your Null Reference checks are only needed for business logic, not boilerplate.