using System; using System.Collections; using System.Collections.Generic; using System.Linq; namespace Microsoft.AspNet.CoreServices { /// /// The default IServiceProvider. /// public class ServiceProvider : IServiceProvider { private readonly IDictionary> _services = new Dictionary>(); private readonly IDictionary>> _priorServices = new Dictionary>>(); /// /// /// public ServiceProvider() { _services[typeof(IServiceProvider)] = () => this; } /// /// Gets the service object of the specified type. /// /// /// public virtual object GetService(Type serviceType) { return GetSingleService(serviceType) ?? GetMultiService(serviceType); } private object GetSingleService(Type serviceType) { Func serviceFactory; return _services.TryGetValue(serviceType, out serviceFactory) ? serviceFactory.Invoke() : null; } private object GetMultiService(Type collectionType) { if (collectionType.IsGenericType && collectionType.GetGenericTypeDefinition() == typeof(IEnumerable<>)) { Type serviceType = collectionType.GetGenericArguments().Single(); Type listType = typeof(List<>).MakeGenericType(serviceType); var services = (IList)Activator.CreateInstance(listType); Func serviceFactory; if (_services.TryGetValue(serviceType, out serviceFactory)) { services.Add(serviceFactory()); List> prior; if (_priorServices.TryGetValue(serviceType, out prior)) { foreach (var factory in prior) { services.Add(factory()); } } } return services; } return null; } /// /// Remove all occurrences of the given type from the provider. /// /// /// public virtual ServiceProvider RemoveAll() { return RemoveAll(typeof(T)); } /// /// Remove all occurrences of the given type from the provider. /// /// /// public virtual ServiceProvider RemoveAll(Type type) { _services.Remove(type); _priorServices.Remove(type); return this; } /// /// Add an instance of type TService to the list of providers. /// /// /// /// public virtual ServiceProvider AddInstance(object instance) { return AddInstance(typeof(TService), instance); } /// /// Add an instance of the given type to the list of providers. /// /// /// /// public virtual ServiceProvider AddInstance(Type service, object instance) { return Add(service, () => instance); } /// /// Specify that services of the type TService should be fulfilled by the type TImplementation. /// /// /// /// public virtual ServiceProvider Add() { return Add(typeof(TService), typeof(TImplementation)); } /// /// Specify that services of the type serviceType should be fulfilled by the type implementationType. /// /// /// /// public virtual ServiceProvider Add(Type serviceType, Type implementationType) { Func factory = ActivatorUtilities.CreateFactory(implementationType); return Add(serviceType, () => factory(this)); } /// /// Specify that services of the given type should be created with the given serviceFactory. /// /// /// /// public virtual ServiceProvider Add(Type serviceType, Func serviceFactory) { Func existing; if (_services.TryGetValue(serviceType, out existing)) { List> prior; if (_priorServices.TryGetValue(serviceType, out prior)) { prior.Add(existing); } else { prior = new List> { existing }; _priorServices.Add(serviceType, prior); } } _services[serviceType] = serviceFactory; return this; } } }