Home > Uncategorized > Designing a .NET application with removable features

Designing a .NET application with removable features

Normally, if you remove a class file from an application, it will just break, but let’s imagine, you want to allow that, so that, a sysops engineer can delete sensitive code from your application that may not be required in a given circumstance.

So, to design an application that will allow you to just delete a file without breaking the application, takes alot of forethought, and here’s one possible way of doing it.

TL;DR; here’s the github repo: https://github.com/infiniteloopltd/PluginDemo

So, First off, I’ll describe this proof of concept application. It has two features, Addition and Subtraction, which are named Addition.cs and Subtraction.cs in the Features folder. Either of these files can be deleted, and it won’t break the application, but evidently the ability to perform that operation will be removed.

So, First, I define an Interface, which features must adhere to; as follows;

namespace PluginDemo
{
    public interface IFeature
    {
        string Description { get; }

        int Execute(int a, int b);
    }
}

So, each feature has a Description, and it can perform some numerical operation on two numbers. Here is how Addition.cs implements this interface;

namespace PluginDemo
{
    class Addition : IFeature
    {
        public string Description
        {
            get
            {
                return "Addition";
            }
        }

        public int Execute(int a, int b)
        {
            return a + b;
        }
    }
}

Now, the magic is in the reflection, where we generate a dynamic list at runtime of all classes in the assembly that implement IFeature. (except IFeature itself), which is defined in a class named FeatureManager

using System;
using System.Collections.Generic;
using System.Reflection;

namespace PluginDemo
{
    public static class FeatureManager
    {
        private static readonly List<IFeature> _features = new List<IFeature>();

        static FeatureManager()
        {
            var dll = Assembly.GetExecutingAssembly();
            foreach (var type in dll.GetTypes())
            {
                if (typeof(IFeature).IsAssignableFrom(type) && !type.IsInterface)
                {
                    _features.Add(Activator.CreateInstance(type) as IFeature);
                }
            }
        }

        public static List<IFeature> Features
        {
            get
            {
                return _features;
            }
        }
    }
}

Now, we can list all available features by calling;

foreach (var feature in FeatureManager.Features)
{
   Console.WriteLine(feature.Description);
}

And, we can use this feature list to check for the availability of a feature, and call it, if it is available.

var addition = FeatureManager.Features.FirstOrDefault(f => f.Description == "Addition");
if (addition != null)
{
  Console.WriteLine("1 + 2 = " + addition.Execute(1,2) );
}

Here, as you can see in the above code. If the file, Addition.cs is deleted, then the addition object is null, but no exception is thrown.

Categories: Uncategorized
  1. No comments yet.
  1. No trackbacks yet.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

%d bloggers like this: