Multiple Inheritance

I you are developing a somewhat bigger project, sooner or later you will find yourself in a situation when you have already wasted your one and only allowed base class and say “It would be nice if this class could also derive from another one”. Well it wouldn’t. But that is a different story. Still, the problem can be solved in different ways:

Of course just the first one is meant seriously.

Let’s first take a look at why we want inheritance in the first place:

Two reasons: Polymorphism and Maintainability.

In my case the focus lies on maintainability. We do not want to have duplicate code. Or to be more specific, no duplicate code that is handwritten and therefore has an impact on maintainability. T4 templates to the rescue! http://msdn.microsoft.com/de-de/library/ee844259(v=vs.100).aspx 

I have some interfaces that many of my classes (ViewModels in my case) have to implement, and those ViewModels already have a base class. The interfaces are used by central behavior and manager classes that help organizing and unifying the user interface. The implementation of those interfaces is always the same, most of them just define some properties and the implementation takes care of the INotifyPropertyChanged.PropertyChanged event being raised properly.

Here is an example of such an interface:

IExecutableItem.cs

   public interface IExecutableItem
   {
        public ICommand Command { get; set; }
        public object CommandParameter { get; set; }
        public event CommandExecutedEventHandler Executed;
   }

Now with the help of T4 templates you can do this:

1.) Your create a partial class for your ViewModel that contains your handwritten code.

MyViewModel.cs

    public partial class MyViewModel : ViewModelBase
    {
        public MyViewModel(IServiceLocator serviceLocator)
            : base(serviceLocator)
        {  }
        // [ more code ... ]
    }

2.) You create a T4 Template File that generates the implementation of additional interfaces:

MyViewModel.ModelProperties.tt

<#@ template hostspecific="true" language="C#" #>
<#@ output extension=".cs" #>
<#@ include file="..\ModelProperties\ModelProperties.tt" #>
<#
	Implement(
		@"..\ModelProperties\",
		"ISelectableItem;IExecutableItem;IOrderedItem"
	);
#>

3.) You are done.

To make this work you need the included file ModelProperties.tt and one .tt file per interface you wish to be implementable in this way. I will give you the interface .tt for the IExecutableItem interface as an example:

IExecutableItem.tt

<#@ template debug="false" hostspecific="true" language="C#" #>
<#@ import namespace="System.Runtime.Remoting.Messaging" #>
<#@ import namespace="System.Collections.Generic" #>
<#@ parameter name="ClassName" type="System.String" #>
<#@ parameter name="Namespace" type="System.String" #>
<#
	var usings = (List<string>)CallContext.GetData("usings");
	usings.Add("using System.Windows.Input;");
	usings.Add("using MyCompany.MyProject.Tools;");
#>
namespace <#=Namespace#>
{

    public partial class <#=ClassName#> : IExecutableItem
    {

        private ICommand _Command;

        /// <summary>
        /// Command
        /// </summary>
        public ICommand Command
        {
            get { return _Command; }
            set
            {
                if (_Command != value)
                {
                    _Command = value;
                    base.RaisePropertyChanged(() => Command);
                }
            }
        }

        private object _CommandParameter;

        /// <summary>
        /// CommandParameter
        /// </summary>
        public object CommandParameter
        {
            get { return _CommandParameter; }
            set
            {
                if (_CommandParameter != value)
                {
                    _CommandParameter = value;
                    base.RaisePropertyChanged(() => CommandParameter);
                }
            }
        }

        private event CommandExecutedEventHandler _Executed;

        /// <summary>
        /// Executed
        /// </summary>
        public event CommandExecutedEventHandler Executed
        {
            add { _Executed += value; }
            remove { _Executed -= value; }
        }

    }

}

and here is the ModelProperties.tt:

<#@ template debug="false" hostspecific="true" language="C#" #>
<#@ output extension=".cs" #>
<#@ assembly name = "System.Core" #>
<#@ import namespace="System.IO" #>
<#@ import namespace="System.Collections.Generic" #>
<#@ import namespace="System.Linq" #>
<#@ import namespace="System.Runtime.Remoting.Messaging" #>
<#@ import namespace="Microsoft.VisualStudio.TextTemplating" #>
<#+

		public void Implement(string path, string interfaces)
		{
			TextTemplatingSession session = new TextTemplatingSession();
			session["Namespace"] = "MyCompany.MyProject.Demo";
			session["ClassName"] = "MyViewModel";
			var usings = new List<string>();
			CallContext.SetData("usings", usings);
			var sessionHost = (ITextTemplatingSessionHost) this.Host;
			sessionHost.Session = session;
			foreach (var item in interfaces.Split(';'))
			{
				GenerationEnvironment.Append(ProcessTemplate(Path.Combine(path, item.Trim() + ".tt")));
			}
			this.GenerationEnvironment.Insert(0, Environment.NewLine);
			foreach (var item in usings.Distinct().OrderByDescending(x => x))
			{
				this.GenerationEnvironment.Insert(0, item + Environment.NewLine);
			}
		}

		public string ProcessTemplate(string templateFileName)
		{
			string templateDirectory = Path.GetDirectoryName(Host.TemplateFile);
			string template = File.ReadAllText(Host.ResolvePath(templateFileName));
			Engine engine = new Engine();
			string output = engine.ProcessTemplate(template, Host);
			return output + Environment.NewLine;
		}

#>

The Implement method creates a session and stores the classname and the namespace in it. It also stores a stringlist in the CallContext to allow the interface .tt’s to add usings to the output. Then each interface .tt is executed and the output is added. Finally the content of the using stringlist is made distinct, sorted and inserted at the top of the generated file.

You end up with a ViewModel that has all the implementations from your interface .tt files. I know this is not “real” inheritance but it serves our main goal: Maintainability. Changes in the interface .tt files will be reflected in all “derived” classes once you hit “Transform all templates” again.

You could also combine this idea with the aforementioned “Simulated Multiple Inheritance Pattern” and make your templates generate all the redirecting methods. That way you would end up being able to also extend classes instead of just interfaces. I’ll leave this to you as a an exercise 😉

This is still not an out-of-the-box solution because you have to make all classes and interfaces “implementable” but usually you have only some base classes and interfaces and many many classes deriving from them.