Skip to content

Instantly share code, notes, and snippets.

@hide1202
Last active August 7, 2017 01:53
Show Gist options
  • Save hide1202/057d33067f2f6e0d8b8bb49826da2a40 to your computer and use it in GitHub Desktop.
Save hide1202/057d33067f2f6e0d8b8bb49826da2a40 to your computer and use it in GitHub Desktop.
Simple IoC(Inversion of Control) implementation test
using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
namespace IocPractice
{
[TestClass]
public class IocPractice
{
internal class IocContainer
{
private Dictionary<Type, Type> _typeDictionary = new Dictionary<Type, Type>();
internal void Register<TBaseType, TDerivedType>()
{
if(_typeDictionary.ContainsKey(typeof(TBaseType)))
throw new ArgumentException("Already assigned a type");
if(!typeof(TBaseType).IsAssignableFrom(typeof(TDerivedType)))
throw new ArgumentException($"{typeof(TDerivedType).Name} type can't assign to {typeof(TBaseType).Name}");
_typeDictionary[typeof(TBaseType)] = typeof(TDerivedType);
}
internal TBaseType Get<TBaseType>()
{
var type = _typeDictionary[typeof(TBaseType)];
return (TBaseType) Get(type);
}
internal object Get(Type type)
{
var defaultConstructor = type.GetConstructor(Type.EmptyTypes);
if (defaultConstructor != null)
return defaultConstructor.Invoke(null);
var constructors = type.GetConstructors();
var constructor = constructors.First(c => c.GetParameters().All(p => _typeDictionary.ContainsKey(p.ParameterType)));
var paramObjs = constructor.GetParameters().Select(p => Get(_typeDictionary[p.ParameterType])).ToArray();
return constructor.Invoke(paramObjs);
}
}
interface IParameter { string Name { get; }}
interface IBase { IParameter Parameter { get; }}
class Parameter : IParameter
{
internal const string Message = "This is parameter";
public string Name { get; } = Message;
}
class Derived : IBase
{
public Derived(IParameter param)
{
Parameter = param;
}
public IParameter Parameter { get; }
}
[TestMethod]
public void InjectionTest()
{
var container = new IocContainer();
container.Register<IBase, Derived>();
container.Register<IParameter, Parameter>();
var testInstance = container.Get<IBase>();
Assert.AreEqual(Parameter.Message, testInstance.Parameter.Name);
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment