Skip to content

Instantly share code, notes, and snippets.

@danbarua
Created February 3, 2016 12:23
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save danbarua/d2c46af82531baa81c7a to your computer and use it in GitHub Desktop.
Save danbarua/d2c46af82531baa81c7a to your computer and use it in GitHub Desktop.
IOC Kata
namespace IOCContainer.Tests
{
using System;
using System.Collections.Generic;
using System.Linq;
using Shouldly;
using Xunit;
public class MagicContainer
{
private readonly IDictionary<Type, Func<object>> registry = new Dictionary<Type, Func<object>>();
public T Resolve<T>()
{
return (T)Resolve(typeof(T));
}
public object Resolve(Type typeToResolve)
{
if ((typeToResolve.IsInterface || typeToResolve.IsAbstract) && !registry.ContainsKey(typeToResolve))
{
throw new HissyFit(string.Format($"You didn't register a type of {typeToResolve.Name}!", typeToResolve));
}
return registry.ContainsKey(typeToResolve)
? registry[typeToResolve].Invoke()
: Activator.CreateInstance(typeToResolve);
}
public void Register<TRequired>()
{
Register<TRequired, TRequired>();
}
public void Register<TRequired, TImpl>()
{
var biggestCtor = typeof(TImpl).GetConstructors().OrderByDescending(x => x.GetParameters().Length).First();
var dependencies = biggestCtor.GetParameters().ToList();
registry.Add(typeof(TRequired), () => biggestCtor.Invoke(dependencies.Select(p => Resolve(p.ParameterType)).ToArray()));
}
}
public class HissyFit : Exception
{
public HissyFit(string message) : base(message)
{
}
}
public class Story1
{
private readonly MagicContainer sut;
public Story1()
{
sut = new MagicContainer();
sut.Register<Foo>();
}
[Fact]
public void can_instatiate_instance_of_foo()
{
var resolved = sut.Resolve<Foo>();
resolved.ShouldNotBeNull();
resolved.ShouldBeOfType<Foo>();
}
public class Foo
{
}
}
public class Story2
{
private readonly MagicContainer sut;
public Story2()
{
sut = new MagicContainer();
sut.Register<Foo>();
}
[Fact]
public void can_instatiate_instance_of_foo()
{
var resolved = sut.Resolve<Foo>();
resolved.ShouldNotBeNull();
resolved.ShouldBeOfType<Foo>();
resolved.Bar.ShouldNotBeNull();
resolved.Bar.ShouldBeOfType<Bar>();
}
public class Foo
{
private readonly Bar bar;
public Foo(Bar bar)
{
this.bar = bar;
}
public Bar Bar => bar;
}
public class Bar
{
}
}
public class Story3
{
private readonly MagicContainer sut;
public Story3()
{
sut = new MagicContainer();
sut.Register<IBar, Bar>();
sut.Register<Foo>();
}
[Fact]
public void can_instatiate_instance_of_foo()
{
var resolved = sut.Resolve<Foo>();
resolved.ShouldNotBeNull();
resolved.ShouldBeOfType<Foo>();
resolved.Bar.ShouldNotBeNull();
resolved.Bar.ShouldBeAssignableTo<IBar>();
}
public class Foo
{
private readonly IBar bar;
public Foo(IBar bar)
{
this.bar = bar;
}
public IBar Bar => bar;
}
public class Bar : IBar
{
}
public interface IBar
{
}
}
public class Story4
{
private readonly MagicContainer sut;
public Story4()
{
sut = new MagicContainer();
sut.Register<Foo>();
}
[Fact]
public void cannot_instantiate_foo()
{
var ex = Should.Throw<HissyFit>(() => sut.Resolve<Foo>());
ex.Message.ShouldBe("You didn't register a type of IBar!");
}
public class Foo
{
private readonly IBar bar;
public Foo(IBar bar)
{
this.bar = bar;
}
public IBar Bar => bar;
}
public class Bar : IBar
{
}
public class IrnBru : IBar
{
}
public interface IBar
{
}
}
public class Story5
{
private readonly MagicContainer sut;
public Story5()
{
sut = new MagicContainer();
sut.Register<IBar, IrnBru>();
sut.Register<Foo>();
}
[Fact]
public void can_instantiate_foo()
{
var resolved = sut.Resolve<Foo>();
resolved.ShouldNotBeNull();
resolved.ShouldBeOfType<Foo>();
resolved.Bar.ShouldNotBeNull();
resolved.Bar.ShouldBeOfType<IrnBru>();
}
public class Foo
{
private readonly IBar bar;
public Foo(IBar bar)
{
this.bar = bar;
}
public IBar Bar => bar;
}
public class Bar : IBar
{
}
public class IrnBru : IBar
{
}
public interface IBar
{
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment