using System;
using System.Collections.Generic;
using System.Reflection;
using System.Linq;
using System.Threading;
using LightInject;
namespace Umbraco.Core.Composing.LightInject
{
///
/// Implements with LightInject.
///
public class LightInjectContainer : IContainer
{
private int _disposed;
///
/// Initializes a new instance of the with a LightInject container.
///
protected LightInjectContainer(ServiceContainer container)
{
Container = container;
}
///
/// Creates a new instance of the class.
///
public static LightInjectContainer Create()
=> new LightInjectContainer(CreateServiceContainer());
///
/// Creates a new instance of the LightInject service container.
///
protected static ServiceContainer CreateServiceContainer()
=> new ServiceContainer(new ContainerOptions { EnablePropertyInjection = false });
///
/// Gets the LightInject container.
///
protected ServiceContainer Container { get; }
///
public object ConcreteContainer => Container;
///
public void Dispose()
{
if (Interlocked.Exchange(ref _disposed, 1) == 1)
return;
Container.Dispose();
}
#region Factory
///
public object GetInstance(Type type)
=> Container.GetInstance(type);
///
public object GetInstance(Type type, string name)
=> Container.GetInstance(type, name);
///
public object GetInstance(Type type, params object[] args)
{
// LightInject has this, but then it requires RegisterConstructorDependency etc and has various oddities
//return Container.GetInstance(type, args);
var ctor = type.GetConstructors(BindingFlags.Instance | BindingFlags.Public).OrderByDescending(x => x.GetParameters().Length).FirstOrDefault();
if (ctor == null) throw new InvalidOperationException($"Could not find a public constructor for type {type.FullName}.");
var ctorParameters = ctor.GetParameters();
var ctorArgs = new object[ctorParameters.Length];
var i = 0;
foreach (var parameter in ctorParameters)
{
// no! IsInstanceOfType is not ok here
// ReSharper disable once UseMethodIsInstanceOfType
var arg = args?.FirstOrDefault(a => parameter.ParameterType.IsAssignableFrom(a.GetType()));
ctorArgs[i++] = arg ?? GetInstance(parameter.ParameterType);
}
return ctor.Invoke(ctorArgs);
}
///
public object TryGetInstance(Type type)
=> Container.TryGetInstance(type);
///
public IEnumerable GetAllInstances()
=> Container.GetAllInstances();
///
public IEnumerable