namespace Caliburn.Micro.Core {
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
///
/// A simple IoC container.
///
public class SimpleContainer {
static readonly Type delegateType = typeof(Delegate);
static readonly Type enumerableType = typeof(IEnumerable);
readonly List entries;
///
/// Initializes a new instance of the class.
///
public SimpleContainer() {
entries = new List();
}
SimpleContainer(IEnumerable entries) {
this.entries = new List(entries);
}
///
/// Registers the instance.
///
/// The service.
/// The key.
/// The implementation.
public void RegisterInstance(Type service, string key, object implementation) {
RegisterHandler(service, key, container => implementation);
}
///
/// Registers the class so that a new instance is created on every request.
///
/// The service.
/// The key.
/// The implementation.
public void RegisterPerRequest(Type service, string key, Type implementation) {
RegisterHandler(service, key, container => container.BuildInstance(implementation));
}
///
/// Registers the class so that it is created once, on first request, and the same instance is returned to all requestors thereafter.
///
/// The service.
/// The key.
/// The implementation.
public void RegisterSingleton(Type service, string key, Type implementation) {
object singleton = null;
RegisterHandler(service, key, container => singleton ?? (singleton = container.BuildInstance(implementation)));
}
///
/// Registers a custom handler for serving requests from the container.
///
/// The service.
/// The key.
/// The handler.
public void RegisterHandler(Type service, string key, Func handler) {
GetOrCreateEntry(service, key).Add(handler);
}
///
/// Unregisters any handlers for the service/key that have previously been registered.
///
/// The service.
/// The key.
public void UnregisterHandler(Type service, string key) {
var entry = GetEntry(service, key);
if (entry != null) {
entries.Remove(entry);
}
}
///
/// Requests an instance.
///
/// The service.
/// The key.
/// The instance, or null if a handler is not found.
public object GetInstance(Type service, string key) {
var entry = GetEntry(service, key);
if (entry != null) {
return entry.Single()(this);
}
if (service == null) {
return null;
}
if (delegateType.IsAssignableFrom(service)) {
var typeToCreate = service.GetGenericArguments()[0];
var factoryFactoryType = typeof(FactoryFactory<>).MakeGenericType(typeToCreate);
var factoryFactoryHost = Activator.CreateInstance(factoryFactoryType);
var factoryFactoryMethod = factoryFactoryType.GetMethod("Create", new Type[] { typeof(SimpleContainer) });
return factoryFactoryMethod.Invoke(factoryFactoryHost, new object[] { this });
}
if (enumerableType.IsAssignableFrom(service) && service.IsGenericType()) {
var listType = service.GetGenericArguments()[0];
var instances = GetAllInstances(listType).ToList();
var array = Array.CreateInstance(listType, instances.Count);
for (var i = 0; i < array.Length; i++) {
array.SetValue(instances[i], i);
}
return array;
}
return null;
}
///
/// Determines if a handler for the service/key has previously been registered.
///
/// The service.
/// The key.
/// True if a handler is registere; false otherwise.
public bool HasHandler(Type service, string key) {
return GetEntry(service, key) != null;
}
///
/// Requests all instances of a given type.
///
/// The service.
/// All the instances or an empty enumerable if none are found.
public IEnumerable