Creating Your Own Custom Dynamic C# Classes

C# provides pre-supplied dynamic types such as the ExpandoObject. It is also possible to create new dynamic types or add dynamic capabilities to existing custom classes.

One of the core interfaces that enables dynamic behaviour is the IDynamicMetaObjectProvider interface. Whilst this interface can be implemented, an easier way to create a custom dynamic class is to inherit from DynamicObject class.

The DynamicObject base class provides a number of virtual methods that allow an instance of the derived class to respond to dynamic operations such as getting or setting the value of a dynamically added property or invocation of a dynamic method.

The following simple example allows adding of arbitrary dynamic properties at runtime. The class overrides the TrySetMember and TryGetMember virtual methods to provide the behaviour. Notice that these methods have a binder parameter that gives information about the dynamic operation that is being attempted, such as the name of the property (binder.Name). Also note that the methods return a Boolean value to indicate to the runtime whether the dynamic operation succeeded.

using System.Collections.Generic;
using System.Dynamic;
using System.Text;

namespace CustomDynamic
{
    class MyDynamicClass : DynamicObject
    {
        private readonly Dictionary<string, object> _dynamicProperties = new Dictionary<string, object>(); 

        public override bool TrySetMember(SetMemberBinder binder, object value)
        {
            _dynamicProperties.Add(binder.Name, value);

            // additional error checking code omitted

            return true;
        }

        public override bool TryGetMember(GetMemberBinder binder, out object result)
        {
            return _dynamicProperties.TryGetValue(binder.Name, out result);
        }

        public override string ToString()
        {
            var sb = new StringBuilder();

            foreach (var property in _dynamicProperties)
            {
                sb.AppendLine($"Property '{property.Key}' = '{property.Value}'");
            }

            return sb.ToString();
        }
    }
}

At runtime, if the instance of the class is declared as dynamic, arbitrary properties can be set as the following simple console application demonstrates:

using System;

namespace CustomDynamic
{
    class Program
    {
        static void Main(string[] args)
        {            
            dynamic d = new MyDynamicClass();

            // Need to declare as dynamic, the following cause compilation errors:
            //      MyDynamicClass d = new MyDynamicClass();
            //      var d = new MyDynamicClass();

            // Dynamically add properties
            d.Name = "Sarah"; // TrySetMember called with binder.Name of "Name"
            d.Age = 42; // TrySetMember called with binder.Name of "Age"

            Console.WriteLine(d.Name); // TryGetMember called
            Console.WriteLine(d.Age); // TryGetMember called

            Console.ReadLine();
        }
    }
}

To learn more about how C# makes dynamic possible, some potential use cases, and more detail on implementing custom types check out my Dynamic C# Fundamentals Pluralsight course.

New Pluralsight Course: Dynamic C# Fundamentals

My Pluralsight course “Dynamic C# Fundamentals” is now available.

The course is split into 4 modules:

Module 1 introduces the dynamic features of C# and how it is enabled by the Dynamic Language Runtime (DLR).

Module 2 looks at numerous places that dynamic C# can be used including COM, XAML, MVC, and JSON.

Module 3 digs into more detail and shows how to create custom C# classes that can exhibit dynamic behaviour.

Module 4 shows how the DLR enables C# to interoperate with other dynamic languages such as IronPython.

Full list of topics:

1 Introducing Dynamic C#

  • Why Dynamic C#?
  • Course Outline
  • Introducing the DLR
  • Static and Dynamic Binding
  • Dynamic Binding in Action and RuntimeBinderException
  • Implicit Dynamic Conversions
  • Var and Dynamic
  • Runtime Method Resolution
  • Dynamic and Object Types
  • Limitations of Callable Methods
  • Introducing ExpandoObject
  • Refactoring to Dynamic
  • Dynamically Adding ExpandoObject Behavior

2 Simplifying Code with Dynamic C#

  • Simplifying Reflection Code
  • Reducing Code with Unified Numeric Methods
  • COM Interop Without Interop Assemblies
  • Reducing Plumbing Code with Dynamic JSON
  • Dynamically Populating Excel with Arbitrary JSON Data
  • Dynamic JSON in Web API
  • ExpandoObject and XAML Databinding
  • Dynamic SQL Query Results with Dapper
  • Improving SpecFlow Test Code with Dynamics
  • Dynamic Code Considerations

3 Creating Custom Dynamic Classes

  • Why Custom Dynamic Classes?
  • The IDynamicMetaObjectProvider Interface
  • The DynamicObject Base Class
  • Creating a Dynamic HtmlElement Class
  • Creating the First Test
  • Adding Initial Dynamic Capabilities
  • Dynamic Operation Exceptions
  • Improving the Debugger Experience
  • Overriding ToString
  • Implementing Additional Interfaces
  • Making the Dynamic Object Enumerable
  • Implementing Dynamic Methods
  • Method Invocation Precedence
  • Invoking the Dynamic Object Itself

4 Interoperating with Dynamic Languages

  • Why Dynamic Interop?
  • Getting Started with IronPython
  • Getting Scripting Input from the User
  • Scripting Risks
  • Executing Python Statements
  • Interacting with Python Objects
  • Passing Custom Dynamic Objects to Python

Check out the full course description.

Writing Implicit and Explicit C# Conversion Operators

When writing custom classes we can provide behaviour to allow for both explicit and implicit conversions to other types.

Implicit conversion operators are those that don’t require an explicit cast.

Explicit conversion operators are those that do require an explicit cast.

As an example, the following code shows a simple console application to covert a weight in Pounds to Kilograms.

internal class Program
{
    private static void Main(string[] args)
    {
        WriteLine("Please enter a value in lbs");
        var lbsText = ReadLine();

        var lbs = new PoundsExplicit(float.Parse(lbsText));
        WriteLine($"\nYou entered {lbs}");

        Kilogram kg = (Kilogram) lbs;
        WriteLine($"\n{lbs} is {kg}");

        WriteLine("\nPress enter to exit");
        ReadLine();
    }
}

Notice in the preceding code the line Kilogram kg = (Kilogram) lbs; is explicitly casting from a type of PoundsExplicit to Kilograms.

The Kilogram class is defined as follows:

internal class Kilogram
{
    public float Weight { get; set; }

    public Kilogram(float weight)
    {
        Weight = weight;
    }

    public override string ToString()
    {
        return $"{Weight} kg";
    }
}

To allow the (explicit) cast from PoundsExplicit to Kilogram, the PoundsExplicit class defines an explicit conversion operator as shown in the following code:

internal class PoundsExplicit
{
    public float Weight { get; set; }

    public PoundsExplicit(float weight)
    {
        Weight = weight;
    }
    public override string ToString()
    {
        return $"{Weight} lbs";
    }

    public static explicit operator Kilogram(PoundsExplicit lbs)
    {
        const float conversionRate = 0.45359237f;

        float equivalentKgs = lbs.Weight * conversionRate;

        return new Kilogram(equivalentKgs);
    }
}

To allow the conversion to Kilogram to be implicit, with no cast required (e.g. Kilogram kg = lbs;) the operator can be changed to implicit as shown in the following class:

internal class PoundsImplicit
{
    public float Weight { get; set; }

    public PoundsImplicit(float weight)
    {
        Weight = weight;
    }       

    public override string ToString()
    {
        return $"{Weight} lbs";
    }

    public static implicit operator Kilogram(PoundsImplicit lbs)
    {
        const float conversionRate = 0.45359237f;

        float equivalentKgs = lbs.Weight * conversionRate;

        return new Kilogram(equivalentKgs);
    }
}

The main method can now be modified as follows:

private static void Main(string[] args)
{
    WriteLine("Please enter a value in lbs");
    var lbsText = ReadLine();

    var lbs = new PoundsImplicit(float.Parse(lbsText));
    WriteLine($"\nYou entered {lbs}");

    Kilogram kg = lbs;
    WriteLine($"\n{lbs} is {kg}");

    WriteLine("\nPress enter to exit");
    ReadLine();
}

Notice in the preceding code the conversion from PoundsImplicit to Kilogram now is implicit, it does not require an explicit cast.

When deciding between implicit or explicit conversion operators you should consider the resulting readability of code that uses the types. An implicit cast is more convenient whereas an explicit cast may add extra clarity/readability to the code that uses the types.

Using the C# 6.0 nameof Operator in ASP.NET MVC Razor Views

Traditionally to reference an action and/or a controller in a Razor view the action/controller name is represented as a string as shown in the following code:

<ul class="nav navbar-nav">
    <li>@Html.ActionLink("Home", "Index", "Home")</li>
    <li>@Html.ActionLink("About", "About", "Home")</li>
    <li>@Html.ActionLink("Contact", "Contact", "Home")</li>
</ul>

This means that some brittleness can be introduced into the application, for example if the name of the controller or action is changed these strings can become outdated and cause a runtime error.

The nameof operator introduced in C# 6.0 gets the (non fully qualified) name of the type passed to it. So for example nameof(HomeController) will return the string “HomeController”. The nameof operator can also be used with type members, for example nameof(HomeController.Index) will return the string “Index”.

The following code shows the use of nameof to get the action name programmatically without needing a magic string:

<ul class="nav navbar-nav">
    <li>@Html.ActionLink("Home", nameof(HomeController.Index), "Home")</li>
    <li>@Html.ActionLink("About", nameof(HomeController.About), "Home")</li>
    <li>@Html.ActionLink("Contact", nameof(HomeController.Contact), "Home")</li>
</ul>

Now if the name of the HomeController.Index method is renamed, for example to HomeController.Index2, there will be a build time error: “'HomeController' does not contain a definition for 'Index'”.

The use of nameof can also be applied to the controller name:

<ul class="nav navbar-nav">
    <li>@Html.ActionLink("Home", nameof(HomeController.Index), nameof(HomeController) )</li>
    <li>@Html.ActionLink("About", nameof(HomeController.About), nameof(HomeController))</li>
    <li>@Html.ActionLink("Contact", nameof(HomeController.Contact), nameof(HomeController))</li>
</ul>

The preceding code however causes errors, the link URL produced is “http://localhost:26663/HomeController/About” rather than the correct “http://localhost:26663/Home/About” (note the extra Controller text).

One way to rectify this would be to remove the word “Controller” from the string produced by nameof:

<ul class="nav navbar-nav">
    <li>@Html.ActionLink("Home", nameof(HomeController.Index), nameof(HomeController).Replace("Controller", ""))</li>
    <li>@Html.ActionLink("About", nameof(HomeController.About), nameof(HomeController).Replace("Controller", ""))</li>
    <li>@Html.ActionLink("Contact", nameof(HomeController.Contact), nameof(HomeController).Replace("Controller", ""))</li>
</ul>

This technique introduces some code duplication, which could be addressed by creating a string extension method:

public static class ControllerExtensions
{
    public static string RemoveController(this string fullControllerClassName)
    {
        return fullControllerClassName.Replace("Controller", "");
    }
}

And then using this extension method:

<ul class="nav navbar-nav">
    <li>@Html.ActionLink("Home", nameof(HomeController.Index), nameof(HomeController).RemoveController())</li>
    <li>@Html.ActionLink("About", nameof(HomeController.About), nameof(HomeController).RemoveController())</li>
    <li>@Html.ActionLink("Contact", nameof(HomeController.Contact), nameof(HomeController).RemoveController()))</li>
</ul>

Alternatively a static method could be created:

public static class ControllerExtensions
{
    public static string ShortControllerName<T>() where T : Controller
    {
        return typeof(T).Name.Replace("Controller", "");
    }
}

And then called from the view:

<ul class="nav navbar-nav">
    <li>@Html.ActionLink("Home", nameof(HomeController.Index), ControllerExtensions.ShortControllerName<HomeController>())</li>
    <li>@Html.ActionLink("About", nameof(HomeController.About), ControllerExtensions.ShortControllerName<HomeController>())</li>
    <li>@Html.ActionLink("Contact", nameof(HomeController.Contact), ControllerExtensions.ShortControllerName<HomeController>())</li>
</ul>

This technique may not work in all situations, for example if an action method is using the [ActionName] attribute:

[ActionName("Contact2")]
public ActionResult Contact()
{    
    // ...
}
In the preceding example, nameof(HomeController.Contact) will return the string “Contact” and the URL “http://localhost:26663/Home/Contact” wheras the correct URL should be “http://localhost:26663/Home/Contact2” because of the [ActionName("Contact2")] attribute.

Note that to get access to nameof, the view needs to be compiled with C# 6.0 language features enabled.

New Pluralsight Course: Automated Business Readable Web Tests with Selenium and SpecFlow

SpecFlow is a tool that can translate natural language scenarios (e.g. writing in English or other spoken languages) into test code. This can allow business people, users, or other stakeholders to verify that the correct features are being built.

Selenium is a tool that allows test code (multiple programming languages supported) to automated a web browser. This allows the creation of automated UI tests that operate the web application as if an end user where doing it; for example clicking buttons and typing text into input boxes.

My new Pluralsight course shows how to integrate these two tools.

The course is organized into four modules:

  1. Introduction to Business Readable Web Testing
  2. Getting Started with Selenium
  3. Adding Business Readability with SpecFlow
  4. Creating More Maintainable Web Automation

If you’re new to SpecFlow I suggest watching this course first before moving on to Automated Business Readable Web Tests with Selenium and SpecFlow.

Your First Xbox One UWP App

image

There’s been a number of almost-goosebump-inspiring moments during my .NET dev experience such as the first time I saw my code running on a Windows Phone 7. Another one of these moments was seeing my code running on my Xbox One for the first time.

(Note: this post describes pre-release technology)

It is now possible to take your regular Fallout 4 playing retail Xbox One and turn it into a development machine. This allows the running of Universal Windows Platform (UWP) apps. At the time of writing this is in preview/pre-release status with a final release expected later this year.

There’s a great set of documentation on MSDN that describes the following steps in detail. I’d recommend reading through them all before starting the process as there’s a number of warnings that should be observed before starting. For example “some popular games and apps will not work as expected, and you may experience occasional crashes and data loss. If you leave the developer preview, your console will factory reset and you will have to reinstall all of your games, apps, and content” [MSDN].

Also be aware that, to enable Xbox UWP app development in Visual Studio, the Windows 10 SDK preview build 14295 needs to be installed: “Installing this preview SDK on your PC will prevent you from submitting apps to the store built on this PC, so don’t do this on your production development PC” [MSDN]. I created a new Hyper-V virtual machine so as not to disturb my base machine.

The documentation recommends using a hardwired network connection rather than wireless for better dev performance, I used wireless and for this simple app and it was fine. Also note “…system performance in this preview does not reflect system performance of the final release” [MSDN].

Also note that you don’t need the latest Windows 10 preview build to install the tools, the virtual machine I created was just running standard Windows 10 Pro, though as the following screenshot shows this seems to mean that there is no XAML visual preview in Visual Studio.

No XAML Preview without Windows 10 insider build


Overview of Steps

The following is an overview of the main steps required, once again you should consult MSDN for full details/steps required/warnings.

Step 1: Development Environment Setup

[MSDN]

You need:

  • Visual Studio 2015 Update 2 or newer (be sure to install the Universal Windows App Development Tools component)
  • Windows 10 SDK preview build 14295
  • Sign up for Windows Insider program
  • Create Windows Dev Center account
  • Network connection to your Xbox One

Step 2: Xbox One Setup

Detailed steps from MSDN.

Sign in to Xbox One.

Install Dev Mode Activation app from Xbox One store

Installing Dev Mode Activation app from Xbox One store

Once installed run the app:

Running Dev Mode Activation app

This can be a bit confusing as to what to do next, basically just leave it alone, at some point (perhaps hours) an “Update your Xbox” prompt will be displayed. Install the update and wait for it to complete and your Xbox restarted.

Open the Dev Mode Activation app again and following the instructions, to switch your console to into dev mode:

Switching Xbox One to developer mode

Tip: Make sure you’re connected to your wireless network before continuing…

Once restart is complete, open the Dev Home app:

Opening the Dev Home app

Take a note of the Xbox One’s IP address:

Xbox One IP Address

Step 3: Connection to Your Xbox One from Visual Studio

Create a new UWP project in Visual Studio.

Open the project properties and choose Remote Machine, enter the Xbox One’s IP address, and choose Universal (Unencrypted protocol).

Configuring Visual Studio to connect to Xbox One

Next run the app, and Visual Studio will ask you for a PIN, head back to the Xbox One dev app, and choose “Pair with Visual Studio”, you’ll be given a PIN that you can type into Visual Studio.

Pairing Visual Studio with Xbox One

Your app should now be installed and run on your Xbox One!

App XAML in Visual Studio

UWP app running on Xbox One

Free eBook C# 6.0: What’s New Quick Start Complete

free C# bok cover image

My new free eBook “C# 6.0: What’s New Quick Start” is now complete and available for download.

The book covers the following:

  • Using Static Type Directive
  • String Interpolation
  • The Null-Conditional Operators
  • Getter Only Auto Properties
  • Using Await in Catch and Finally Blocks
  • Property, Dictionary, and Index Initializers
  • The nameof Operator
  • Expression Bodied Functions and Properties
  • Exception Filters
  • Visual Studio 2015 and C# 6

You can download it for free or pay what you think it is worth.

Happy reading!

New Pluralsight Course: Business Readable Automated Tests with SpecFlow 2.0

My newest Pluralsight course was just published. Business Readable Automated Tests with SpecFlow 2.0 teaches how to create tests that the business can read, understand, and contribute to. These “English-like” tests (other spoken languages are supported) can be executed by writing test code that is associated with the “English-like” steps. Because the tests sit alongside the source code, they can become living (executable) documentation for the system, as opposed to an out-of-date Word document somewhere on the network for example. Check out the course here.

New Free eBook C# 6.0: What’s New Quick Start

C# 6 eBook Cover Image

The first chapters of my new free eBook have just been published.

The book will cover the new features added in C# 6.0 and provide a quick start to those new to version 6 or as a handy reference to those already using C# 6.0

New chapters are being added periodically and you can get the version now and get access to new chapters as they are published.

You can download the book for free or pay what you think it’s worth.

New Pluralsight Course: Getting Started Building Windows Services with Topshelf

My newest Pluralsight course “Getting Started Building Windows Services with Topshelf” has just been released.

Topshelf is an open source library that makes it easier to develop, test, and install Windows Services.

If you’re new to Windows Services, the course starts by introducing how Windows Services work and some of their features such as automatic service recovery and the ability to run in the background as different users.

The course then goes on to cover how to create a Windows Service with Topshelf as well as additional techniques such as debugging, logging, pause and continue and the ability to send custom commands to running services.

Check out the course link or browse all my Pluralsight courses.