Monday, October 22, 2012

Dependency Injection: Inversion of Control

Inversion of Control

The first thing to consider when planning an advanced architecture is support of extensions. Many platforms support tools and other extras, as independently compiled components. In general this is only possible when the references are soft coded.

Architecture Overview

To build an inversion of control framework from the ground up, we`ll focus on three modules - The main application, A library with helper utilities, and a component that we`ll use in the application without referencing it directly during the compilation.
We will use the standard app.config file to soft code the information about the component, divided in two parts - the assembly name that we need to build the path to the DLL file and the class name for instantiating the component at run-time using reflection. This is part of the first module - the application.

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<appSettings>
<add key="IComponentModule" value="SampleComponent.dll" />
<add key="IComponentClass" value="SampleComponent.SampleComponent" />
</appSettings>
</configuration>

And a very simplified interface of the component. This is part of the common library module:

public interface IComponent
{
string GetResult();
}

Basic Dependency Injection Framework

First we`ll implement the framework that handles the dependency injection functionality, and next we`ll build the whole sample application. Basically we need a couple of methods in a class Tools (that could be a singleton). This class is supposed to be in the common library module as well:

The first method is a generic approach to read values from a standard App.config file:

private static T GetCfgValue<T>(string key)
{
try
{
var value = ConfigurationManager.AppSettings[key];
return (T)Convert.ChangeType(value, typeof(T));
}
catch
{
return default(T);
}
}

The next part is loading the assembly:

private static Assembly GetModuleByType(Type interfaceType)
{
string toolName = interfaceType.Name;
string assemblyPath = Assembly.GetExecutingAssembly().Location;

string dir = Path.GetDirectoryName(assemblyPath);
string file = GetCfgValue<string>(toolName + "Module");
string modulePath = Path.Combine(dir, file);
return Assembly.LoadFile(modulePath);
}

And getting the component type:

private static Type GetType<T>()
{
string toolName = typeof(T).Name;
string CfgTypeKey = toolName + "Class";
var module = GetModuleByType(typeof(T));
return module.GetType(GetCfgValue<string>(CfgTypeKey));
}

And the last thing is the only public method in our Tools singleton, that provides the API for instancing components dynamically, by a given interface:

public static T GetInstance<T>()
{
var type = GetType<T>();
return (T)Activator.CreateInstance(type);
}

The Independently Compiled Component

So far we have the app.config file from the application, and the common library module that contains the interface of the component and the basic inversion of control framework. Now we`ll implement the component with an API specified in the interface, which has a single method for brevity.

public class SampleComponent : IComponent
{
public string GetResult()
{
return "This is a sample result";
}
}

Putting it all together

At this point we have everything we need to instantiate the component, from the main application that has no reference to it during the compilation at all. However creating an instance of that class is as easy as:

class Program
{
static void Main(string[] args)
{
var instance = Tools.GetInstance<IComponent>();
Console.WriteLine(instance.GetResult());
}
}

Once we have a framework for instancing classes from different modules by a given interface, we can easily add a setup utility to our application to allow switching between different implementations of different application plugins.

The next steps

From this point we can look at even higher level of abstraction - loading modules from the cloud, to allow updates which do not require patching every installation of the software and more benefits in general. We will cover this topic later too.

2 comments:

  1. Casinos that offer Free Spins No Deposit | Top 10 casinos
    Most Popular Casinos: Slots Casino · 1. 유로 스타 사이트 Wild Casino · 2. 사이트 추천 BetMGM 바카라 Casino · 3. Bovegas 1xbet korean Casino · 4. kadangpintar Wild Casino.

    ReplyDelete
  2. With the adoption of pill kiosks inside bookmakers, the instore expertise brings the usability of the cellular apps with the sociability of the bookmaker. With integrated 우리카지노 devices from printing tickets, money acceptors, to scanning loyalty cards, pill kiosks present the usability of the cellular apps with the performance of the integrated devices. By way of comparison, New Jersey presents an 8.5% tax fee for in-person sports wagering and a 13% online tax, whereas Pennsylvania holds a a lot greater 36% fee. In doing so, Colorado turned the nineteenth U.S. state to legalize sports betting. Last year, BetMGM transitioned its online sportsbook to model new}, more trendy platform, which is out there in Colorado. It’s not quite as feature-rich as its online-first sites, however it’s surprisingly good, properly laid out, and absolutely featured.

    ReplyDelete