Created
February 3, 2016 12:23
-
-
Save danbarua/d2c46af82531baa81c7a to your computer and use it in GitHub Desktop.
IOC Kata
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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