using System;
using System.Collections.Generic;
namespace SmallInjector
{
///
/// A small dependency injector to demonstrate the pattern.
///
public class Container : IContainer
{
private readonly Dictionary _container = new Dictionary();
///
public void RegisterType(bool isSingleton, TService instance = default)
where TService : TInterface
{
_container.Add(typeof(TInterface), new RegisteredType(typeof(TService), isSingleton, null));
}
///
public void RegisterType(bool isSingleton, TService instance = default) =>
RegisterType(isSingleton, instance);
///
public TService Resolve() => (TService) Resolve(typeof(TService));
///
public bool IsRegistered() => IsRegistered(typeof(TService));
///
public bool IsRegistered(Type serviceType) => _container.ContainsKey(serviceType);
///
public object Resolve(Type serviceInterface)
{
if (!_container.TryGetValue(serviceInterface, out var registeredType))
throw new Exception(@"Dependency {serviceInterface} is not registered");
if (registeredType.IsSingleton && registeredType.Instance != null)
return registeredType.Instance;
var constructor = registeredType.ServiceType.GetConstructors()[0];
var parameters = constructor.GetParameters();
var constructorParameters = new object[parameters.Length];
for (var i = 0; i < parameters.Length; i++)
{
constructorParameters[i] = Resolve(parameters[i].ParameterType);
}
var instance = constructor.Invoke(constructorParameters);
return registeredType.IsSingleton ? (registeredType.Instance = instance) : instance;
}
private class RegisteredType
{
public bool IsSingleton { get; }
public Type ServiceType { get; }
public object Instance { get; set; }
public RegisteredType(Type serviceType, bool isSingleton, object instance)
{
ServiceType = serviceType;
IsSingleton = isSingleton;
Instance = instance;
}
}
}
}