The Inner Drive Extensible Architecture™—the Idea™

Demonstration: Quantitative classes

This measurement conversion applet demonstrates some of the core features of Inner Drive Extensible Architecture™—the Idea™.

Convert something

Language
Unit type
Convert from
Value to convert
Convert to

* = default unit for the measurement class.

Buy a license

If you want to use the IDEA™ in your commercial application, check out our licensing options.

Language choice

You're using the English (United States) culture.

Internationalization and localization are built into the framework from the start. But we're still missing a few translations here and there (which is why you sometimes see a mix of U.S. English and other languages). So please help us by help us by reporting translation errors.

How this works

We're pleased to announce that we've put a partial SDK up on the site, so you can see what we've been up to. (Important note: This is living product documentation, subject to change at any point.)

Each of the principal types of measurement—area, length, speed, etc.—is a distinct .NET structure. This means that the compiler, not the developer, controls what kind of measurements are possible for a particular phenomenon.

However, all of the built-in measurement structures implement IMeasurable, which defines a number of properties and methods useful for a generic converter like this one.

The framework also defines an abstract Unit class, and a collection of concrete measurement units that derive from it. Each contains its own list of conversion factors, meaning that measurements can convert directly to other measurements without going through an intermediary; and the conversion framework is completely extensible, since new Unit classes can simply define their own conversion list.

Converting measurements becomes trivial in most cases:

Length meters = new Length(3000d); // defaults to meters
Length feet = meters.ConvertTo(typeof(Foot));

// feet.ToString("0.0000") yields "9842.5197 ft."

Even compound units, such as those used for Speed and Pressure, are easy to handle:

var psi = new ForceOverArea(new Pound(), new InchSquare());
var pressure = new Pressure(29.92d, psi);
var atmospheres = pressure.ConvertTo(typeof(Atmosphere));

(This, incidentally, is why Speed and Pressure have so few conversions available in this demo. We are working on making the demo aware of compound units.)

But even in a generic case, like this conversion utility, the appropriate use of interfaces and abstractions makes it not much more complicated than the more common, concrete case. This is the salient code behind this Web form:

using InnerDrive.Quantitative;

private void Convert()
{
	var fromUnit = CreateUnit(convertFromList.SelectedValue);
	var toUnit = GetType(convertToList.SelectedValue);
	var rawValue = 0d;
	double.TryParse(convertFromBox.Text, out rawValue);

	var result = string.Empty;
	try
	{
		var from = CreateMeasure(measureTypeList.SelectedValue, rawValue, fromUnit);
		var converted = from.ConvertTo(toUnit);

		var fromText = FormattedMeasure(from);
		var toText = FormattedMeasure(converted);

		result = String.Format("{0} = {1}", fromText, toText);
	}
	catch
	{
		// Handle various exceptions
	}

	resultText.Text = result;
}

private static IMeasurable CreateMeasure(
	string className, 
	double value, 
	Unit unit)
{
	var assembly = typeof(Time).Assembly;
	var args = GetArguments(value, unit);
	var type = assembly.GetType(className);
	return (IMeasurable)Activator.CreateInstance(type, args);
}

private static string FormattedMeasure(IMeasurable measure)
{
	var formatText = 
		measure.ToString(DefaultFormat, MetricExponent.Unit, CultureInfo.CurrentCulture);

	if (measure.Value == 0d) return formatText;
	
	// Multiple 'if' block is quick and dirty; a more elaborate, reflection-based
	// approach is possible
	if (measure.Value < .0001d)
	{
		formatText =
			measure.ToString(DefaultFormat, MetricExponent.Micro, CultureInfo.CurrentCulture);
	}
	else if (measure.Value < .1d)
	{
		formatText =
			measure.ToString(DefaultFormat, MetricExponent.Milli, CultureInfo.CurrentCulture);
	}
	else if (measure.Value > 100d)
	{
		formatText =
			measure.ToString(DefaultFormat, MetricExponent.Kilo, CultureInfo.CurrentCulture);
	}
	else if (measure.Value > 100000d)
	{
		formatText =
			measure.ToString(DefaultFormat, MetricExponent.Mega, CultureInfo.CurrentCulture);
	}
	return formatText;
}

private static Unit CreateUnit(string className)
{
	object unit = Activator.CreateInstance(GetType(className));
	return (InnerDrive.Quantitative.Unit)unit;
}

private static Type GetType(string className)
{
	var assembly = typeof(Time).Assembly;
	return assembly.GetType(className, false);
}
	

InnerDrive.Quantitative 3.1.5251.1 Release CLR 4.0.30319.34014
Copyright ©2014 Inner Drive Technology. All rights reserved. Portions Copyright ©1986-2013 David Braverman.

Return home.

Copyright ©2014 Inner Drive Technology. Purveyors of fine, hand-crafted computer software. Legal information. Page printed 2014-10-24T16:08:54 UTC.