After playing a little with Inversion of Control Containers... and being annoyed by the backing of a Hash Table or Dictionary, I decided to use some generic magic. And just for giggles I tossed in some .Net 3.5 Extension method love. Oh, as a warning... I build this on VS2010 Beta 1 so the Range object's constructor has optional parameters. Please feel free to leave questions and comments. -Thanks, Matt
using System;
using System.Collections.Generic;
using System.Linq;
using System.Collections;
namespace GenericIoCandDI
{
// quick and pointless example
class Program
{
static void Main(string[] args)
{
new List().Register>();
new List().Register();
new List().Register>();
GIoC>.Get.AddRange(0.ToRange(10));
GIoC>.Get.AddRange(20.ToRange(30));
GIoC>.Get.AddRange(10.ToRange(0, -1).Select(v => (uint)v));
//0,1,2,3,4,5,6,7,8,9,10
Console.WriteLine(string.Join(",", GIoC>.Get.Select(i => i.ToString()).ToArray()));
//20,21,22,23,24,25,26,27,28,29,30
Console.WriteLine(string.Join(",", GIoC>.Get.Select(i => i.ToString()).ToArray()));
//10,9,8,7,6,5,4,3,2,1,0
Console.WriteLine(string.Join(",", GIoC>.Get.Select(i => i.ToString()).ToArray()));
Console.ReadLine();
}
}
//IoC Container
public static class GIoC
{
private static T _instance;
public static void Register(T instance)
{
if (instance == null)
throw new ArgumentNullException("instance");
if (_instance != null)
throw new InvalidOperationException("instance already registered");
_instance = instance;
}
public static T Get
{
get
{
if (_instance == null)
throw new InvalidOperationException("instance not registered");
return _instance;
}
}
}
//Extension Method Register magic
public static class Extensions
{
public static void Register(this T instance)
{
GIoC.Register(instance);
}
public static void AddRange(this IList list, IEnumerable range)
{
foreach (var item in range)
list.Add(item);
}
public static Range ToRange(this int start, int end = 0, int step = 1)
{
return new Range(start, end, step);
}
}
//I find this to be some handy plumbing
public class Range : IEnumerable
{
public Range(int start = 0, int end = 0, int step = 1)
{
this.Start = start;
this.End = end;
this.Step = step;
}
public int Start { get; private set; }
public int End { get; private set; }
public int Step { get; private set; }
#region IEnumerable Members
public IEnumerator GetEnumerator()
{
if (Step > 0)
for (int i = this.Start; i <= this.End; i += this.Step)
yield return i;
else if (Step < 0)
for (int i = this.Start; i >= this.End; i += this.Step)
yield return i;
}
#endregion
#region IEnumerable Members
IEnumerator IEnumerable.GetEnumerator()
{
throw new NotImplementedException();
}
#endregion
}
}