From 0bcf38b267486c4f1854ff39489cd6e7c37bbb7c Mon Sep 17 00:00:00 2001 From: Shannon Date: Sun, 20 Dec 2015 17:09:46 +0100 Subject: [PATCH] Removes LightInject as Source and adds it as DLL dependencies, updates to latest Light Inject. --- src/Umbraco.Core/CoreBootManager.cs | 2 +- .../CultureDictionaryFactoryResolver.cs | 4 +- src/Umbraco.Core/LightInject/LightInject.cs | 6067 ----------------- .../LightInject/LightInjectExtensions.cs | 1015 --- src/Umbraco.Core/LightInjectExtensions.cs | 88 + .../PublishedContentModelFactoryResolver.cs | 2 +- .../ContainerLazyManyObjectsResolver.cs | 2 +- .../ContainerManyObjectsResolver.cs | 2 +- .../ContainerSingleObjectResolver.cs | 4 +- .../ObjectResolution/ResolverBase.cs | 2 +- .../Persistence/Mappers/MappingResolver.cs | 2 +- .../Migrations/MigrationResolver.cs | 2 +- .../ParameterEditorResolver.cs | 2 +- .../PropertyEditors/PropertyEditorResolver.cs | 2 +- .../PropertyValueConvertersResolver.cs | 2 +- .../Strings/ShortStringHelperResolver.cs | 4 +- .../Strings/UrlSegmentProviderResolver.cs | 2 +- .../Sync/ServerMessengerResolver.cs | 4 +- .../Sync/ServerRegistrarResolver.cs | 4 +- src/Umbraco.Core/Umbraco.Core.csproj | 7 +- src/Umbraco.Core/UmbracoApplicationBase.cs | 2 +- src/Umbraco.Core/packages.config | 2 +- .../DistributedCache/DistributedCacheTests.cs | 2 +- .../PublishedMediaCacheTests.cs | 2 +- src/Umbraco.Tests/LibraryTests.cs | 1 - .../Migrations/FindingMigrationsTest.cs | 2 +- .../TargetVersionSixthMigrationsTest.cs | 1 - .../Migrations/Upgrades/BaseUpgradeTest.cs | 1 - .../PublishedContentMoreTests.cs | 1 - .../PublishedContentTestBase.cs | 1 - .../PublishedContent/PublishedMediaTests.cs | 2 +- .../TestHelpers/BaseUmbracoApplicationTest.cs | 2 +- .../TestHelpers/BaseUsingSqlCeSyntax.cs | 4 +- src/Umbraco.Tests/Umbraco.Tests.csproj | 4 + src/Umbraco.Tests/packages.config | 1 + .../LightInject/Mvc/LightInject.Mvc.cs | 203 - .../LightInject/Web/LightInject.Web.cs | 164 - .../LightInject/WebApi/LightInject.WebApi.cs | 235 - .../LightInjectExtensions.cs | 11 +- .../ThumbnailProvidersResolver.cs | 2 +- .../PublishedCache/PublishedCachesResolver.cs | 4 +- .../Routing/ContentFinderResolver.cs | 2 +- .../ContentLastChanceFinderResolver.cs | 4 +- .../Routing/SiteDomainHelperResolver.cs | 4 +- .../Routing/UrlProviderResolver.cs | 2 +- src/Umbraco.Web/Umbraco.Web.csproj | 21 +- src/Umbraco.Web/WebBootManager.cs | 6 +- src/Umbraco.Web/app.config | 4 + src/Umbraco.Web/packages.config | 7 +- 49 files changed, 167 insertions(+), 7749 deletions(-) delete mode 100644 src/Umbraco.Core/LightInject/LightInject.cs delete mode 100644 src/Umbraco.Core/LightInject/LightInjectExtensions.cs create mode 100644 src/Umbraco.Core/LightInjectExtensions.cs delete mode 100644 src/Umbraco.Web/LightInject/Mvc/LightInject.Mvc.cs delete mode 100644 src/Umbraco.Web/LightInject/Web/LightInject.Web.cs delete mode 100644 src/Umbraco.Web/LightInject/WebApi/LightInject.WebApi.cs rename src/Umbraco.Web/{LightInject => }/LightInjectExtensions.cs (87%) diff --git a/src/Umbraco.Core/CoreBootManager.cs b/src/Umbraco.Core/CoreBootManager.cs index ec98c7a755..fc569b83f3 100644 --- a/src/Umbraco.Core/CoreBootManager.cs +++ b/src/Umbraco.Core/CoreBootManager.cs @@ -5,13 +5,13 @@ using System.Linq; using System.Threading.Tasks; using System.Threading; using AutoMapper; +using LightInject; using Umbraco.Core.Cache; using Umbraco.Core.Configuration; using Umbraco.Core.Configuration.UmbracoSettings; using Umbraco.Core.Events; using Umbraco.Core.Exceptions; using Umbraco.Core.IO; -using Umbraco.Core.LightInject; using Umbraco.Core.Logging; using Umbraco.Core.Manifest; using Umbraco.Core.Models.Mapping; diff --git a/src/Umbraco.Core/Dictionary/CultureDictionaryFactoryResolver.cs b/src/Umbraco.Core/Dictionary/CultureDictionaryFactoryResolver.cs index cf0227d2a3..f2f7632cb4 100644 --- a/src/Umbraco.Core/Dictionary/CultureDictionaryFactoryResolver.cs +++ b/src/Umbraco.Core/Dictionary/CultureDictionaryFactoryResolver.cs @@ -1,7 +1,7 @@ using System; using System.Linq.Expressions; using System.ComponentModel; -using Umbraco.Core.LightInject; +using LightInject; using Umbraco.Core.ObjectResolution; namespace Umbraco.Core.Dictionary @@ -31,7 +31,7 @@ namespace Umbraco.Core.Dictionary /// /// /// - internal CultureDictionaryFactoryResolver(IServiceContainer container, Expression> implementationType) + internal CultureDictionaryFactoryResolver(IServiceContainer container, Func implementationType) : base(container, implementationType) { } diff --git a/src/Umbraco.Core/LightInject/LightInject.cs b/src/Umbraco.Core/LightInject/LightInject.cs deleted file mode 100644 index 5077aa251c..0000000000 --- a/src/Umbraco.Core/LightInject/LightInject.cs +++ /dev/null @@ -1,6067 +0,0 @@ -/********************************************************************************* - The MIT License (MIT) - - Copyright (c) 2014 bernhard.richter@gmail.com - - Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated documentation files (the "Software"), to deal - in the Software without restriction, including without limitation the rights - to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - copies of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included in all - copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - SOFTWARE. -****************************************************************************** - LightInject version 3.0.2.2 - http://www.lightinject.net/ - http://twitter.com/bernhardrichter -******************************************************************************/ -[module: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.ReadabilityRules", "SA1126:PrefixCallsCorrectly", Justification = "Reviewed")] -[module: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.ReadabilityRules", "SA1101:PrefixLocalCallsWithThis", Justification = "No inheritance")] -[module: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.MaintainabilityRules", "SA1402:FileMayOnlyContainASingleClass", Justification = "Single source file deployment.")] -[module: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.DocumentationRules", "SA1633:FileMustHaveHeader", Justification = "Custom header.")] -[module: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.DocumentationRules", "SA1600:ElementsMustBeDocumented", Justification = "All public members are documented.")] -[module: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.MaintainabilityRules", "SA1401:FieldsMustBePrivate", Justification = "Performance")] - -namespace Umbraco.Core.LightInject -{ - using System; - using System.Collections.Concurrent; - using System.Collections.Generic; - using System.Collections.ObjectModel; - using System.IO; - using System.Linq; - using System.Linq.Expressions; - using System.Reflection; - using System.Reflection.Emit; - using System.Runtime.CompilerServices; - using System.Runtime.Remoting.Messaging; - using System.Text; - using System.Text.RegularExpressions; - using System.Threading; - - /// - /// Defines a set of methods used to register services into the service container. - /// - internal interface IServiceRegistry - { - /// - /// Gets a list of instances that represents the - /// registered services. - /// - IEnumerable AvailableServices { get; } - - /// - /// Registers the with the . - /// - /// The service type to register. - /// The implementing type. - void Register(Type serviceType, Type implementingType); - - /// - /// Registers the with the . - /// - /// The service type to register. - /// The implementing type. - /// The instance that controls the lifetime of the registered service. - void Register(Type serviceType, Type implementingType, ILifetime lifetime); - - /// - /// Registers the with the . - /// - /// The service type to register. - /// The implementing type. - /// The name of the service. - void Register(Type serviceType, Type implementingType, string serviceName); - - /// - /// Registers the with the . - /// - /// The service type to register. - /// The implementing type. - /// The name of the service. - /// The instance that controls the lifetime of the registered service. - void Register(Type serviceType, Type implementingType, string serviceName, ILifetime lifetime); - - /// - /// Registers the with the . - /// - /// The service type to register. - /// The implementing type. - void Register() where TImplementation : TService; - - /// - /// Registers the with the . - /// - /// The service type to register. - /// The implementing type. - /// The instance that controls the lifetime of the registered service. - void Register(ILifetime lifetime) where TImplementation : TService; - - /// - /// Registers the with the . - /// - /// The service type to register. - /// The implementing type. - /// The name of the service. - void Register(string serviceName) where TImplementation : TService; - - /// - /// Registers the with the . - /// - /// The service type to register. - /// The implementing type. - /// The name of the service. - /// The instance that controls the lifetime of the registered service. - void Register(string serviceName, ILifetime lifetime) where TImplementation : TService; - - /// - /// Registers the with the given . - /// - /// The service type to register. - /// The instance returned when this service is requested. - void RegisterInstance(TService instance); - - /// - /// Registers the with the given . - /// - /// The service type to register. - /// The instance returned when this service is requested. - /// The name of the service. - void RegisterInstance(TService instance, string serviceName); - - /// - /// Registers the with the given . - /// - /// The service type to register. - /// The instance returned when this service is requested. - void RegisterInstance(Type serviceType, object instance); - - /// - /// Registers the with the given . - /// - /// The service type to register. - /// The instance returned when this service is requested. - /// The name of the service. - void RegisterInstance(Type serviceType, object instance, string serviceName); - - /// - /// Registers a concrete type as a service. - /// - /// The service type to register. - void Register(); - - /// - /// Registers a concrete type as a service. - /// - /// The service type to register. - /// The instance that controls the lifetime of the registered service. - void Register(ILifetime lifetime); - - /// - /// Registers a concrete type as a service. - /// - /// The concrete type to register. - void Register(Type serviceType); - - /// - /// Registers a concrete type as a service. - /// - /// The concrete type to register. - /// The instance that controls the lifetime of the registered service. - void Register(Type serviceType, ILifetime lifetime); - - /// - /// Registers the with the that - /// describes the dependencies of the service. - /// - /// The service type to register. - /// A factory delegate used to create the instance. - void Register(Expression> factory); - - /// - /// Registers the with the that - /// describes the dependencies of the service. - /// - /// The parameter type. - /// The service type to register. - /// A factory delegate used to create the instance. - void Register(Expression> factory); - - /// - /// Registers the with the that - /// describes the dependencies of the service. - /// - /// The parameter type. - /// The service type to register. - /// A factory delegate used to create the instance. - /// The name of the service. - void Register(Expression> factory, string serviceName); - - /// - /// Registers the with the that - /// describes the dependencies of the service. - /// - /// The type of the first parameter. - /// The type of the second parameter. - /// The service type to register. - /// A factory delegate used to create the instance. - void Register(Expression> factory); - - /// - /// Registers the with the that - /// describes the dependencies of the service. - /// - /// The type of the first parameter. - /// The type of the second parameter. - /// The service type to register. - /// A factory delegate used to create the instance. - /// The name of the service. - void Register(Expression> factory, string serviceName); - - /// - /// Registers the with the that - /// describes the dependencies of the service. - /// - /// The type of the first parameter. - /// The type of the second parameter. - /// The type of the third parameter. - /// The service type to register. - /// A factory delegate used to create the instance. - void Register(Expression> factory); - - /// - /// Registers the with the that - /// describes the dependencies of the service. - /// - /// The type of the first parameter. - /// The type of the second parameter. - /// The type of the third parameter. - /// The service type to register. - /// A factory delegate used to create the instance. - /// The name of the service. - void Register(Expression> factory, string serviceName); - - /// - /// Registers the with the that - /// describes the dependencies of the service. - /// - /// The type of the first parameter. - /// The type of the second parameter. - /// The type of the third parameter. - /// The type of the fourth parameter. - /// The service type to register. - /// A factory delegate used to create the instance. - void Register(Expression> factory); - - /// - /// Registers the with the that - /// describes the dependencies of the service. - /// - /// The type of the first parameter. - /// The type of the second parameter. - /// The type of the third parameter. - /// The type of the fourth parameter. - /// The service type to register. - /// A factory delegate used to create the instance. - /// The name of the service. - void Register(Expression> factory, string serviceName); - - /// - /// Registers the with the that - /// describes the dependencies of the service. - /// - /// The service type to register. - /// The lambdaExpression that describes the dependencies of the service. - /// The instance that controls the lifetime of the registered service. - void Register(Expression> factory, ILifetime lifetime); - - /// - /// Registers the with the that - /// describes the dependencies of the service. - /// - /// The service type to register. - /// The lambdaExpression that describes the dependencies of the service. - /// The name of the service. - void Register(Expression> factory, string serviceName); - - /// - /// Registers the with the that - /// describes the dependencies of the service. - /// - /// The service type to register. - /// The lambdaExpression that describes the dependencies of the service. - /// The name of the service. - /// The instance that controls the lifetime of the registered service. - void Register(Expression> factory, string serviceName, ILifetime lifetime); - - /// - /// Registers a custom factory delegate used to create services that is otherwise unknown to the service container. - /// - /// Determines if the service can be created by the delegate. - /// Creates a service instance according to the predicate. - void RegisterFallback(Func predicate, Func factory); - - /// - /// Registers a custom factory delegate used to create services that is otherwise unknown to the service container. - /// - /// Determines if the service can be created by the delegate. - /// Creates a service instance according to the predicate. - /// The instance that controls the lifetime of the registered service. - void RegisterFallback(Func predicate, Func factory, ILifetime lifetime); - - /// - /// Registers a service based on a instance. - /// - /// The instance that contains service metadata. - void Register(ServiceRegistration serviceRegistration); - - /// - /// Registers composition roots from the given . - /// - /// The assembly to be scanned for services. - /// - /// If the target contains an implementation of the interface, this - /// will be used to configure the container. - /// - void RegisterAssembly(Assembly assembly); - - /// - /// Registers services from the given . - /// - /// The assembly to be scanned for services. - /// A function delegate that determines if a service implementation should be registered. - /// - /// If the target contains an implementation of the interface, this - /// will be used to configure the container. - /// - void RegisterAssembly(Assembly assembly, Func shouldRegister); - - /// - /// Registers services from the given . - /// - /// The assembly to be scanned for services. - /// The instance that controls the lifetime of the registered service. - /// - /// If the target contains an implementation of the interface, this - /// will be used to configure the container. - /// - void RegisterAssembly(Assembly assembly, Func lifetime); - - /// - /// Registers services from the given . - /// - /// The assembly to be scanned for services. - /// The factory that controls the lifetime of the registered service. - /// A function delegate that determines if a service implementation should be registered. - /// - /// If the target contains an implementation of the interface, this - /// will be used to configure the container. - /// - void RegisterAssembly(Assembly assembly, Func lifetimeFactory, Func shouldRegister); - - /// - /// Registers services from the given type. - /// - /// The type of to register from. - void RegisterFrom() where TCompositionRoot : ICompositionRoot, new(); - - /// - /// Registers composition roots from assemblies in the base directory that matches the . - /// - /// The search pattern used to filter the assembly files. - void RegisterAssembly(string searchPattern); - - /// - /// Decorates the with the given . - /// - /// The target service type. - /// The decorator type used to decorate the . - /// A function delegate that determines if the - /// should be applied to the target . - void Decorate(Type serviceType, Type decoratorType, Func predicate); - - /// - /// Decorates the with the given . - /// - /// The target service type. - /// The decorator type used to decorate the . - void Decorate(Type serviceType, Type decoratorType); - - /// - /// Decorates the with the given . - /// - /// The target service type. - /// The decorator type used to decorate the . - void Decorate() where TDecorator : TService; - - /// - /// Decorates the using the given decorator . - /// - /// The target service type. - /// A factory delegate used to create a decorator instance. - void Decorate(Expression> factory); - - /// - /// Registers a decorator based on a instance. - /// - /// The instance that contains the decorator metadata. - void Decorate(DecoratorRegistration decoratorRegistration); - - /// - /// Allows a registered service to be overridden by another . - /// - /// A function delegate that is used to determine the service that should be - /// overridden using the returned from the . - /// The factory delegate used to create a that overrides - /// the incoming . - void Override( - Func serviceSelector, - Func serviceRegistrationFactory); - } - - /// - /// Defines a set of methods used to retrieve service instances. - /// - internal interface IServiceFactory - { - /// - /// Starts a new . - /// - /// - Scope BeginScope(); - - /// - /// Ends the current . - /// - void EndCurrentScope(); - - /// - /// Gets an instance of the given . - /// - /// The type of the requested service. - /// The requested service instance. - object GetInstance(Type serviceType); - - /// - /// Gets an instance of the given . - /// - /// The type of the requested service. - /// The arguments to be passed to the target instance. - /// The requested service instance. - object GetInstance(Type serviceType, object[] arguments); - - /// - /// Gets an instance of the given . - /// - /// The type of the requested service. - /// The name of the requested service. - /// The arguments to be passed to the target instance. - /// The requested service instance. - object GetInstance(Type serviceType, string serviceName, object[] arguments); - - /// - /// Gets a named instance of the given . - /// - /// The type of the requested service. - /// The name of the requested service. - /// The requested service instance. - object GetInstance(Type serviceType, string serviceName); - - /// - /// Gets an instance of the given type. - /// - /// The type of the requested service. - /// The requested service instance. - TService GetInstance(); - - /// - /// Gets a named instance of the given . - /// - /// The type of the requested service. - /// The name of the requested service. - /// The requested service instance. - TService GetInstance(string serviceName); - - /// - /// Gets an instance of the given . - /// - /// The type of the argument. - /// The type of the requested service. - /// The argument value. - /// The requested service instance. - TService GetInstance(T value); - - /// - /// Gets an instance of the given . - /// - /// The type of the parameter. - /// The type of the requested service. - /// The argument value. - /// The name of the requested service. - /// The requested service instance. - TService GetInstance(T value, string serviceName); - - /// - /// Gets an instance of the given . - /// - /// The type of the first parameter. - /// The type of the second parameter. - /// The type of the requested service. - /// The first argument value. - /// The second argument value. - /// The requested service instance. - TService GetInstance(T1 arg1, T2 arg2); - - /// - /// Gets an instance of the given . - /// - /// The type of the first parameter. - /// The type of the second parameter. - /// The type of the requested service. - /// The first argument value. - /// The second argument value. - /// The name of the requested service. - /// The requested service instance. - TService GetInstance(T1 arg1, T2 arg2, string serviceName); - - /// - /// Gets an instance of the given . - /// - /// The type of the first parameter. - /// The type of the second parameter. - /// The type of the third parameter. - /// The type of the requested service. - /// The first argument value. - /// The second argument value. - /// The third argument value. - /// The requested service instance. - TService GetInstance(T1 arg1, T2 arg2, T3 arg3); - - /// - /// Gets an instance of the given . - /// - /// The type of the first parameter. - /// The type of the second parameter. - /// The type of the third parameter. - /// The type of the requested service. - /// The first argument value. - /// The second argument value. - /// The third argument value. - /// The name of the requested service. - /// The requested service instance. - TService GetInstance(T1 arg1, T2 arg2, T3 arg3, string serviceName); - - /// - /// Gets an instance of the given . - /// - /// The type of the first parameter. - /// The type of the second parameter. - /// The type of the third parameter. - /// The type of the fourth parameter. - /// The type of the requested service. - /// The first argument value. - /// The second argument value. - /// The third argument value. - /// The fourth argument value. - /// The requested service instance. - TService GetInstance(T1 arg1, T2 arg2, T3 arg3, T4 arg4); - - /// - /// Gets an instance of the given . - /// - /// The type of the first parameter. - /// The type of the second parameter. - /// The type of the third parameter. - /// The type of the fourth parameter. - /// The type of the requested service. - /// The first argument value. - /// The second argument value. - /// The third argument value. - /// The fourth argument value. - /// The name of the requested service. - /// The requested service instance. - TService GetInstance(T1 arg1, T2 arg2, T3 arg3, T4 arg4, string serviceName); - - /// - /// Gets an instance of the given . - /// - /// The type of the requested service. - /// The requested service instance if available, otherwise null. - object TryGetInstance(Type serviceType); - - /// - /// Gets a named instance of the given . - /// - /// The type of the requested service. - /// The name of the requested service. - /// The requested service instance if available, otherwise null. - object TryGetInstance(Type serviceType, string serviceName); - - /// - /// Tries to get an instance of the given type. - /// - /// The type of the requested service. - /// The requested service instance if available, otherwise default(T). - TService TryGetInstance(); - - /// - /// Tries to get an instance of the given type. - /// - /// The type of the requested service. - /// The name of the requested service. - /// The requested service instance if available, otherwise default(T). - TService TryGetInstance(string serviceName); - - /// - /// Gets all instances of the given . - /// - /// The type of services to resolve. - /// A list that contains all implementations of the . - IEnumerable GetAllInstances(Type serviceType); - - /// - /// Gets all instances of type . - /// - /// The type of services to resolve. - /// A list that contains all implementations of the type. - IEnumerable GetAllInstances(); - - /// - /// Creates an instance of a concrete class. - /// - /// The type of class for which to create an instance. - /// An instance of . - /// The concrete type will be registered if not already registered with the container. - TService Create() where TService : class; - - /// - /// Creates an instance of a concrete class. - /// - /// The type of class for which to create an instance. - /// An instance of the . - object Create(Type serviceType); - } - - /// - /// Represents an inversion of control container. - /// - internal interface IServiceContainer : IServiceRegistry, IServiceFactory, IDisposable - { - /// - /// Gets or sets the that is responsible - /// for providing the used to manage scopes. - /// - IScopeManagerProvider ScopeManagerProvider { get; set; } - - /// - /// Returns true if the container can create the requested service, otherwise false. - /// - /// The of the service. - /// The name of the service. - /// true if the container can create the requested service, otherwise false. - bool CanGetInstance(Type serviceType, string serviceName); - - /// - /// Injects the property dependencies for a given . - /// - /// The target instance for which to inject its property dependencies. - /// The with its property dependencies injected. - object InjectProperties(object instance); - } - - /// - /// Represents a class that manages the lifetime of a service instance. - /// - internal interface ILifetime - { - /// - /// Returns a service instance according to the specific lifetime characteristics. - /// - /// The function delegate used to create a new service instance. - /// The of the current service request. - /// The requested services instance. - object GetInstance(Func createInstance, Scope scope); - } - - /// - /// Represents a class that acts as a composition root for an instance. - /// - internal interface ICompositionRoot - { - /// - /// Composes services by adding services to the . - /// - /// The target . - void Compose(IServiceRegistry serviceRegistry); - } - - /// - /// Represents a class that extracts a set of types from an . - /// - internal interface ITypeExtractor - { - /// - /// Extracts types found in the given . - /// - /// The for which to extract types. - /// A set of types found in the given . - Type[] Execute(Assembly assembly); - } - - /// - /// Represents a class that is responsible for selecting injectable properties. - /// - internal interface IPropertySelector - { - /// - /// Selects properties that represents a dependency from the given . - /// - /// The for which to select the properties. - /// A list of injectable properties. - IEnumerable Execute(Type type); - } - - /// - /// Represents a class that is responsible for selecting the property dependencies for a given . - /// - internal interface IPropertyDependencySelector - { - /// - /// Selects the property dependencies for the given . - /// - /// The for which to select the property dependencies. - /// A list of instances that represents the property - /// dependencies for the given . - IEnumerable Execute(Type type); - } - - /// - /// Represents a class that is responsible for selecting the constructor dependencies for a given . - /// - internal interface IConstructorDependencySelector - { - /// - /// Selects the constructor dependencies for the given . - /// - /// The for which to select the constructor dependencies. - /// A list of instances that represents the constructor - /// dependencies for the given . - IEnumerable Execute(ConstructorInfo constructor); - } - - /// - /// Represents a class that is capable of building a instance - /// based on a . - /// - internal interface IConstructionInfoBuilder - { - /// - /// Returns a instance based on the given . - /// - /// The for which to return a instance. - /// A instance that describes how to create a service instance. - ConstructionInfo Execute(Registration registration); - } - - /// - /// Represents a class that keeps track of a instance for each . - /// - internal interface IConstructionInfoProvider - { - /// - /// Gets a instance for the given . - /// - /// The for which to get a instance. - /// The instance that describes how to create an instance of the given . - ConstructionInfo GetConstructionInfo(Registration registration); - - /// - /// Invalidates the and causes new instances - /// to be created when the method is called. - /// - void Invalidate(); - } - - /// - /// Represents a class that builds a instance based on a . - /// - internal interface ILambdaConstructionInfoBuilder - { - /// - /// Parses the and returns a instance. - /// - /// The to parse. - /// A instance. - ConstructionInfo Execute(LambdaExpression lambdaExpression); - } - - /// - /// Represents a class that builds a instance based on the implementing . - /// - internal interface ITypeConstructionInfoBuilder - { - /// - /// Analyzes the and returns a instance. - /// - /// The that represents the implementing type to analyze. - /// A instance. - ConstructionInfo Execute(Registration registration); - } - - /// - /// Represents a class that selects the constructor to be used for creating a new service instance. - /// - internal interface IConstructorSelector - { - /// - /// Selects the constructor to be used when creating a new instance of the . - /// - /// The for which to return a . - /// A instance that represents the constructor to be used - /// when creating a new instance of the . - ConstructorInfo Execute(Type implementingType); - } - - /// - /// Represents a class that is responsible loading a set of assemblies based on the given search pattern. - /// - internal interface IAssemblyLoader - { - /// - /// Loads a set of assemblies based on the given . - /// - /// The search pattern to use. - /// A list of assemblies based on the given . - IEnumerable Load(string searchPattern); - } - - /// - /// Represents a class that is capable of scanning an assembly and register services into an instance. - /// - internal interface IAssemblyScanner - { - /// - /// Scans the target and registers services found within the assembly. - /// - /// The to scan. - /// The target instance. - /// The instance that controls the lifetime of the registered service. - /// A function delegate that determines if a service implementation should be registered. - void Scan(Assembly assembly, IServiceRegistry serviceRegistry, Func lifetime, Func shouldRegister); - - /// - /// Scans the target and executes composition roots found within the . - /// - /// The to scan. - /// The target instance. - void Scan(Assembly assembly, IServiceRegistry serviceRegistry); - } - - /// - /// Represents a class that is responsible for instantiating and executing an . - /// - internal interface ICompositionRootExecutor - { - /// - /// Creates an instance of the and executes the method. - /// - /// The concrete type to be instantiated and executed. - void Execute(Type compositionRootType); - } - - /// - /// Represents an abstraction of the class that provides information - /// about the currently on the stack. - /// - internal interface IEmitter - { - /// - /// Gets the currently on the stack. - /// - Type StackType { get; } - - /// - /// Gets a list containing each to be emitted into the dynamic method. - /// - List Instructions { get; } - - /// - /// Puts the specified instruction onto the stream of instructions. - /// - /// The Microsoft Intermediate Language (MSIL) instruction to be put onto the stream. - void Emit(OpCode code); - - /// - /// Puts the specified instruction and numerical argument onto the Microsoft intermediate language (MSIL) stream of instructions. - /// - /// The MSIL instruction to be put onto the stream. - /// The numerical argument pushed onto the stream immediately after the instruction. - void Emit(OpCode code, int arg); - - /// - /// Puts the specified instruction and numerical argument onto the Microsoft intermediate language (MSIL) stream of instructions. - /// - /// The MSIL instruction to be put onto the stream. - /// The numerical argument pushed onto the stream immediately after the instruction. - void Emit(OpCode code, sbyte arg); - - /// - /// Puts the specified instruction and numerical argument onto the Microsoft intermediate language (MSIL) stream of instructions. - /// - /// The MSIL instruction to be put onto the stream. - /// The numerical argument pushed onto the stream immediately after the instruction. - void Emit(OpCode code, byte arg); - - /// - /// Puts the specified instruction onto the Microsoft intermediate language (MSIL) stream followed by the metadata token for the given type. - /// - /// The MSIL instruction to be put onto the stream. - /// A representing the type metadata token. - void Emit(OpCode code, Type type); - - /// - /// Puts the specified instruction and metadata token for the specified constructor onto the Microsoft intermediate language (MSIL) stream of instructions. - /// - /// The MSIL instruction to be emitted onto the stream. - /// A representing a constructor. - void Emit(OpCode code, ConstructorInfo constructor); - - /// - /// Puts the specified instruction onto the Microsoft intermediate language (MSIL) stream followed by the index of the given local variable. - /// - /// The MSIL instruction to be emitted onto the stream. - /// A local variable. - void Emit(OpCode code, LocalBuilder localBuilder); - - /// - /// Puts the specified instruction onto the Microsoft intermediate language (MSIL) stream followed by the metadata token for the given method. - /// - /// The MSIL instruction to be emitted onto the stream. - /// A representing a method. - void Emit(OpCode code, MethodInfo methodInfo); - - /// - /// Declares a local variable of the specified type. - /// - /// A object that represents the type of the local variable. - /// The declared local variable. - LocalBuilder DeclareLocal(Type type); - } - - /// - /// Represents a dynamic method skeleton for emitting the code needed to resolve a service instance. - /// - internal interface IMethodSkeleton - { - /// - /// Gets the for the this dynamic method. - /// - /// The for this dynamic method. - IEmitter GetEmitter(); - - /// - /// Completes the dynamic method and creates a delegate that can be used to execute it. - /// - /// A delegate type whose signature matches that of the dynamic method. - /// A delegate of the specified type, which can be used to execute the dynamic method. - Delegate CreateDelegate(Type delegateType); - } - - /// - /// Represents a class that is capable of providing the current . - /// - internal interface IScopeManagerProvider - { - /// - /// Returns the that is responsible for managing scopes. - /// - /// The that is responsible for managing scopes. - ScopeManager GetScopeManager(); - } - - /// - /// Extends the class. - /// - [System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage] - internal static class ExpressionExtensions - { - /// - /// Flattens the into an . - /// - /// The target . - /// The represented as a list of sub expressions. - public static IEnumerable AsEnumerable(this Expression expression) - { - var flattener = new ExpressionTreeFlattener(); - return flattener.Flatten(expression); - } - - private class ExpressionTreeFlattener : ExpressionVisitor - { - private readonly ICollection nodes = new Collection(); - - public IEnumerable Flatten(Expression expression) - { - Visit(expression); - return nodes; - } - - public override Expression Visit(Expression node) - { - nodes.Add(node); - return base.Visit(node); - } - } - } - - /// - /// Extends the class. - /// - [System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage] - internal static class ImmutableHashTreeExtensions - { - /// - /// Searches for a using the given . - /// - /// The type of the key. - /// The type of the value. - /// The target . - /// The key of the to get. - /// If found, the with the given , otherwise the default . - public static TValue Search(this ImmutableHashTree tree, TKey key) - { - int hashCode = key.GetHashCode(); - - while (tree.Height != 0 && tree.HashCode != hashCode) - { - tree = hashCode < tree.HashCode ? tree.Left : tree.Right; - } - - if (!tree.IsEmpty && (ReferenceEquals(tree.Key, key) || Equals(tree.Key, key))) - { - return tree.Value; - } - - if (tree.Duplicates.Items.Length > 0) - { - foreach (var keyValue in tree.Duplicates.Items) - { - if (ReferenceEquals(keyValue.Key, key) || Equals(keyValue.Key, key)) - { - return keyValue.Value; - } - } - } - - return default(TValue); - } - - /// - /// Adds a new element to the . - /// - /// The type of the key. - /// The type of the value. - /// The target . - /// The key to be associated with the value. - /// The value to be added to the tree. - /// A new that contains the new key/value pair. - public static ImmutableHashTree Add(this ImmutableHashTree tree, TKey key, TValue value) - { - if (tree.IsEmpty) - { - return new ImmutableHashTree(key, value, tree, tree); - } - - int hashCode = key.GetHashCode(); - - if (hashCode > tree.HashCode) - { - return AddToRightBranch(tree, key, value); - } - - if (hashCode < tree.HashCode) - { - return AddToLeftBranch(tree, key, value); - } - - return new ImmutableHashTree(key, value, tree); - } - - private static ImmutableHashTree AddToLeftBranch(ImmutableHashTree tree, TKey key, TValue value) - { - return new ImmutableHashTree(tree.Key, tree.Value, tree.Left.Add(key, value), tree.Right); - } - - private static ImmutableHashTree AddToRightBranch(ImmutableHashTree tree, TKey key, TValue value) - { - return new ImmutableHashTree(tree.Key, tree.Value, tree.Left, tree.Right.Add(key, value)); - } - } - - [System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage] - internal static class LazyTypeExtensions - { - private static readonly ThreadSafeDictionary Constructors = new ThreadSafeDictionary(); - - public static ConstructorInfo GetLazyConstructor(this Type type) - { - return Constructors.GetOrAdd(type, GetConstructor); - } - - private static ConstructorInfo GetConstructor(Type type) - { - Type closedGenericLazyType = typeof(Lazy<>).MakeGenericType(type); - return closedGenericLazyType.GetConstructor(new[] { type.GetFuncType() }); - } - } - - [System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage] - internal static class EnumerableTypeExtensions - { - private static readonly ThreadSafeDictionary EnumerableTypes = new ThreadSafeDictionary(); - - public static Type GetEnumerableType(this Type returnType) - { - return EnumerableTypes.GetOrAdd(returnType, CreateEnumerableType); - } - - private static Type CreateEnumerableType(Type type) - { - return typeof(IEnumerable<>).MakeGenericType(type); - } - } - - [System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage] - internal static class FuncTypeExtensions - { - private static readonly ThreadSafeDictionary FuncTypes = new ThreadSafeDictionary(); - - public static Type GetFuncType(this Type returnType) - { - return FuncTypes.GetOrAdd(returnType, CreateFuncType); - } - - private static Type CreateFuncType(Type type) - { - return typeof(Func<>).MakeGenericType(type); - } - } - - [System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage] - internal static class LifetimeHelper - { - static LifetimeHelper() - { - GetInstanceMethod = typeof(ILifetime).GetMethod("GetInstance"); - GetCurrentScopeMethod = typeof(ScopeManager).GetProperty("CurrentScope").GetGetMethod(); - GetScopeManagerMethod = typeof(IScopeManagerProvider).GetMethod("GetScopeManager"); - } - - public static MethodInfo GetInstanceMethod { get; private set; } - - public static MethodInfo GetCurrentScopeMethod { get; private set; } - - public static MethodInfo GetScopeManagerMethod { get; private set; } - } - - [System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage] - internal static class DelegateTypeExtensions - { - private static readonly MethodInfo OpenGenericGetInstanceMethodInfo = - typeof(IServiceFactory).GetMethod("GetInstance", new Type[] { }); - - private static readonly ThreadSafeDictionary GetInstanceMethods = - new ThreadSafeDictionary(); - - public static Delegate CreateGetInstanceDelegate(this Type serviceType, IServiceFactory serviceFactory) - { - Type delegateType = serviceType.GetFuncType(); - MethodInfo getInstanceMethod = GetInstanceMethods.GetOrAdd(serviceType, CreateGetInstanceMethod); - return getInstanceMethod.CreateDelegate(delegateType, serviceFactory); - } - - private static MethodInfo CreateGetInstanceMethod(Type type) - { - return OpenGenericGetInstanceMethodInfo.MakeGenericMethod(type); - } - } - - [System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage] - internal static class NamedDelegateTypeExtensions - { - private static readonly MethodInfo CreateInstanceDelegateMethodInfo = - typeof(NamedDelegateTypeExtensions).GetPrivateStaticMethod("CreateInstanceDelegate"); - - private static readonly ThreadSafeDictionary CreateInstanceDelegateMethods = - new ThreadSafeDictionary(); - - public static Delegate CreateNamedGetInstanceDelegate(this Type serviceType, string serviceName, IServiceFactory factory) - { - MethodInfo createInstanceDelegateMethodInfo = CreateInstanceDelegateMethods.GetOrAdd( - serviceType, - CreateClosedGenericCreateInstanceDelegateMethod); - - return (Delegate)createInstanceDelegateMethodInfo.Invoke(null, new object[] { factory, serviceName }); - } - - private static MethodInfo CreateClosedGenericCreateInstanceDelegateMethod(Type type) - { - return CreateInstanceDelegateMethodInfo.MakeGenericMethod(type); - } - - // ReSharper disable UnusedMember.Local - private static Func CreateInstanceDelegate(IServiceFactory factory, string serviceName) - // ReSharper restore UnusedMember.Local - { - return () => factory.GetInstance(serviceName); - } - } - - [System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage] - internal static class ReflectionHelper - { - private static readonly Lazy> GetInstanceWithParametersMethods; - - static ReflectionHelper() - { - GetInstanceWithParametersMethods = CreateLazyGetInstanceWithParametersMethods(); - } - - public static MethodInfo GetGetInstanceWithParametersMethod(Type serviceType) - { - return GetInstanceWithParametersMethods.Value.GetOrAdd(serviceType, CreateGetInstanceWithParametersMethod); - } - - public static Delegate CreateGetNamedInstanceWithParametersDelegate(IServiceFactory factory, Type delegateType, string serviceName) - { - Type[] genericTypeArguments = delegateType.GetGenericTypeArguments(); - var openGenericMethod = - typeof(ReflectionHelper).GetPrivateStaticMethods() - .Single( - m => - m.GetGenericArguments().Length == genericTypeArguments.Length - && m.Name == "CreateGenericGetNamedParameterizedInstanceDelegate"); - var closedGenericMethod = openGenericMethod.MakeGenericMethod(genericTypeArguments); - return (Delegate)closedGenericMethod.Invoke(null, new object[] { factory, serviceName }); - } - - private static Lazy> CreateLazyGetInstanceWithParametersMethods() - { - return new Lazy>( - () => new ThreadSafeDictionary()); - } - - private static MethodInfo CreateGetInstanceWithParametersMethod(Type serviceType) - { - Type[] genericTypeArguments = serviceType.GetGenericTypeArguments(); - MethodInfo openGenericMethod = - typeof(IServiceFactory).GetMethods().Single(m => m.Name == "GetInstance" - && m.GetGenericArguments().Length == genericTypeArguments.Length && m.GetParameters().All(p => p.Name != "serviceName")); - - MethodInfo closedGenericMethod = openGenericMethod.MakeGenericMethod(genericTypeArguments); - - return closedGenericMethod; - } - - // ReSharper disable UnusedMember.Local - private static Func CreateGenericGetNamedParameterizedInstanceDelegate(IServiceFactory factory, string serviceName) - // ReSharper restore UnusedMember.Local - { - return arg => factory.GetInstance(arg, serviceName); - } - - // ReSharper disable UnusedMember.Local - private static Func CreateGenericGetNamedParameterizedInstanceDelegate(IServiceFactory factory, string serviceName) - // ReSharper restore UnusedMember.Local - { - return (arg1, arg2) => factory.GetInstance(arg1, arg2, serviceName); - } - - // ReSharper disable UnusedMember.Local - private static Func CreateGenericGetNamedParameterizedInstanceDelegate(IServiceFactory factory, string serviceName) - // ReSharper restore UnusedMember.Local - { - return (arg1, arg2, arg3) => factory.GetInstance(arg1, arg2, arg3, serviceName); - } - - // ReSharper disable UnusedMember.Local - private static Func CreateGenericGetNamedParameterizedInstanceDelegate(IServiceFactory factory, string serviceName) - // ReSharper restore UnusedMember.Local - { - return (arg1, arg2, arg3, arg4) => factory.GetInstance(arg1, arg2, arg3, arg4, serviceName); - } - } - - [System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage] - internal static class TypeHelper - { - public static Type[] GetGenericTypeArguments(this Type type) - { - return type.GetGenericArguments(); - } - - public static bool IsClass(this Type type) - { - return type.IsClass; - } - - public static bool IsAbstract(this Type type) - { - return type.IsAbstract; - } - - public static bool IsNestedPrivate(this Type type) - { - return type.IsNestedPrivate; - } - - public static bool IsGenericType(this Type type) - { - return type.IsGenericType; - } - - public static bool ContainsGenericParameters(this Type type) - { - return type.ContainsGenericParameters; - } - - public static Type GetBaseType(this Type type) - { - return type.BaseType; - } - - public static bool IsGenericTypeDefinition(this Type type) - { - return type.IsGenericTypeDefinition; - } - - public static Assembly GetAssembly(this Type type) - { - return type.Assembly; - } - - public static bool IsValueType(this Type type) - { - return type.IsValueType; - } - - public static MethodInfo GetMethodInfo(this Delegate del) - { - return del.Method; - } - - public static MethodInfo GetPrivateMethod(this Type type, string name) - { - return type.GetMethod(name, BindingFlags.Instance | BindingFlags.NonPublic); - } - - public static MethodInfo GetPrivateStaticMethod(this Type type, string name) - { - return type.GetMethod(name, BindingFlags.Static | BindingFlags.NonPublic); - } - - public static MethodInfo[] GetPrivateStaticMethods(this Type type) - { - return type.GetMethods(BindingFlags.Static | BindingFlags.NonPublic); - } - - public static IEnumerable GetCustomAttributes(this Assembly assembly, Type attributeType) - { - return assembly.GetCustomAttributes(attributeType, false).Cast(); - } - - public static bool IsEnumerableOfT(this Type serviceType) - { - return serviceType.IsGenericType() && serviceType.GetGenericTypeDefinition() == typeof(IEnumerable<>); - } - - public static bool IsListOfT(this Type serviceType) - { - return serviceType.IsGenericType() && serviceType.GetGenericTypeDefinition() == typeof(IList<>); - } - - public static bool IsCollectionOfT(this Type serviceType) - { - return serviceType.IsGenericType() && serviceType.GetGenericTypeDefinition() == typeof(ICollection<>); - } - - public static bool IsReadOnlyCollectionOfT(this Type serviceType) - { - return serviceType.IsGenericType() && serviceType.GetGenericTypeDefinition() == typeof(IReadOnlyCollection<>); - } - - public static bool IsReadOnlyListOfT(this Type serviceType) - { - return serviceType.IsGenericType() && serviceType.GetGenericTypeDefinition() == typeof(IReadOnlyList<>); - } - - public static bool IsLazy(this Type serviceType) - { - return serviceType.IsGenericType() && serviceType.GetGenericTypeDefinition() == typeof(Lazy<>); - } - - public static bool IsFunc(this Type serviceType) - { - return serviceType.IsGenericType() && serviceType.GetGenericTypeDefinition() == typeof(Func<>); - } - - public static bool IsFuncWithParameters(this Type serviceType) - { - if (!serviceType.IsGenericType()) - { - return false; - } - - Type genericTypeDefinition = serviceType.GetGenericTypeDefinition(); - - return genericTypeDefinition == typeof(Func<,>) || genericTypeDefinition == typeof(Func<,,>) - || genericTypeDefinition == typeof(Func<,,,>) || genericTypeDefinition == typeof(Func<,,,,>); - } - - public static bool IsClosedGeneric(this Type serviceType) - { - return serviceType.IsGenericType() && !serviceType.IsGenericTypeDefinition(); - } - - public static Type GetElementType(Type type) - { - if (type.IsGenericType() && type.GetGenericTypeArguments().Count() == 1) - { - return type.GetGenericTypeArguments()[0]; - } - - return type.GetElementType(); - } - } - - /// - /// Extends the interface with a set of methods - /// that optimizes and simplifies emitting MSIL instructions. - /// - [System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage] - internal static class EmitterExtensions - { - /// - /// Performs a cast or unbox operation if the current is - /// different from the given . - /// - /// The target . - /// The requested stack type. - public static void UnboxOrCast(this IEmitter emitter, Type type) - { - if (!type.IsAssignableFrom(emitter.StackType)) - { - emitter.Emit(type.IsValueType() ? OpCodes.Unbox_Any : OpCodes.Castclass, type); - } - } - - /// - /// Pushes a constant value onto the evaluation stack. - /// - /// The target . - /// The index of the constant value to be pushed onto the stack. - /// The requested stack type. - public static void PushConstant(this IEmitter emitter, int index, Type type) - { - emitter.PushConstant(index); - emitter.UnboxOrCast(type); - } - - /// - /// Pushes a constant value onto the evaluation stack as a object reference. - /// - /// The target . - /// The index of the constant value to be pushed onto the stack. - public static void PushConstant(this IEmitter emitter, int index) - { - emitter.PushArgument(0); - emitter.Push(index); - emitter.PushArrayElement(); - } - - /// - /// Pushes the element containing an object reference at a specified index onto the stack. - /// - /// The target . - public static void PushArrayElement(this IEmitter emitter) - { - emitter.Emit(OpCodes.Ldelem_Ref); - } - - /// - /// Pushes the arguments associated with a service request onto the stack. - /// The arguments are found as an array in the last element of the constants array - /// that is passed into the dynamic method. - /// - /// The target . - /// A list of instances that - /// represent the arguments to be pushed onto the stack. - public static void PushArguments(this IEmitter emitter, ParameterInfo[] parameters) - { - var argumentArray = emitter.DeclareLocal(typeof(object[])); - emitter.Emit(OpCodes.Ldarg_0); - emitter.Emit(OpCodes.Ldarg_0); - emitter.Emit(OpCodes.Ldlen); - emitter.Emit(OpCodes.Conv_I4); - emitter.Emit(OpCodes.Ldc_I4_1); - emitter.Emit(OpCodes.Sub); - emitter.Emit(OpCodes.Ldelem_Ref); - emitter.Emit(OpCodes.Castclass, typeof(object[])); - emitter.Emit(OpCodes.Stloc, argumentArray); - - for (int i = 0; i < parameters.Length; i++) - { - emitter.Emit(OpCodes.Ldloc, argumentArray); - emitter.Emit(OpCodes.Ldc_I4, i); - emitter.Emit(OpCodes.Ldelem_Ref); - emitter.Emit( - parameters[i].ParameterType.IsValueType() ? OpCodes.Unbox_Any : OpCodes.Castclass, - parameters[i].ParameterType); - } - } - - /// - /// Calls a late-bound method on an object, pushing the return value onto the stack. - /// - /// The target . - /// The that represents the method to be called. - public static void Call(this IEmitter emitter, MethodInfo methodInfo) - { - emitter.Emit(OpCodes.Callvirt, methodInfo); - } - - /// - /// Pushes a new instance onto the stack. - /// - /// The target . - /// The that represent the object to be created. - public static void New(this IEmitter emitter, ConstructorInfo constructorInfo) - { - emitter.Emit(OpCodes.Newobj, constructorInfo); - } - - /// - /// Pushes the given onto the stack. - /// - /// The target . - /// The to be pushed onto the stack. - public static void Push(this IEmitter emitter, LocalBuilder localBuilder) - { - int index = localBuilder.LocalIndex; - switch (index) - { - case 0: - emitter.Emit(OpCodes.Ldloc_0); - return; - case 1: - emitter.Emit(OpCodes.Ldloc_1); - return; - case 2: - emitter.Emit(OpCodes.Ldloc_2); - return; - case 3: - emitter.Emit(OpCodes.Ldloc_3); - return; - } - - if (index <= 255) - { - emitter.Emit(OpCodes.Ldloc_S, (byte)index); - } - else - { - emitter.Emit(OpCodes.Ldloc, index); - } - } - - /// - /// Pushes an argument with the given onto the stack. - /// - /// The target . - /// The index of the argument to be pushed onto the stack. - public static void PushArgument(this IEmitter emitter, int index) - { - switch (index) - { - case 0: - emitter.Emit(OpCodes.Ldarg_0); - return; - case 1: - emitter.Emit(OpCodes.Ldarg_1); - return; - case 2: - emitter.Emit(OpCodes.Ldarg_2); - return; - case 3: - emitter.Emit(OpCodes.Ldarg_3); - return; - } - - if (index <= 255) - { - emitter.Emit(OpCodes.Ldarg_S, (byte)index); - } - else - { - emitter.Emit(OpCodes.Ldarg, index); - } - } - - /// - /// Stores the value currently on top of the stack in the given . - /// - /// The target . - /// The for which the value is to be stored. - public static void Store(this IEmitter emitter, LocalBuilder localBuilder) - { - int index = localBuilder.LocalIndex; - switch (index) - { - case 0: - emitter.Emit(OpCodes.Stloc_0); - return; - case 1: - emitter.Emit(OpCodes.Stloc_1); - return; - case 2: - emitter.Emit(OpCodes.Stloc_2); - return; - case 3: - emitter.Emit(OpCodes.Stloc_3); - return; - } - - if (index <= 255) - { - emitter.Emit(OpCodes.Stloc_S, (byte)index); - } - else - { - emitter.Emit(OpCodes.Stloc, index); - } - } - - /// - /// Pushes a new array of the given onto the stack. - /// - /// The target . - /// The element of the new array. - public static void PushNewArray(this IEmitter emitter, Type elementType) - { - emitter.Emit(OpCodes.Newarr, elementType); - } - - /// - /// Pushes an value onto the stack. - /// - /// The target . - /// The value to be pushed onto the stack. - public static void Push(this IEmitter emitter, int value) - { - switch (value) - { - case 0: - emitter.Emit(OpCodes.Ldc_I4_0); - return; - case 1: - emitter.Emit(OpCodes.Ldc_I4_1); - return; - case 2: - emitter.Emit(OpCodes.Ldc_I4_2); - return; - case 3: - emitter.Emit(OpCodes.Ldc_I4_3); - return; - case 4: - emitter.Emit(OpCodes.Ldc_I4_4); - return; - case 5: - emitter.Emit(OpCodes.Ldc_I4_5); - return; - case 6: - emitter.Emit(OpCodes.Ldc_I4_6); - return; - case 7: - emitter.Emit(OpCodes.Ldc_I4_7); - return; - case 8: - emitter.Emit(OpCodes.Ldc_I4_8); - return; - } - - if (value > -129 && value < 128) - { - emitter.Emit(OpCodes.Ldc_I4_S, (sbyte)value); - } - else - { - emitter.Emit(OpCodes.Ldc_I4, value); - } - } - - /// - /// Performs a cast of the value currently on top of the stack to the given . - /// - /// The target . - /// The for which the value will be casted into. - public static void Cast(this IEmitter emitter, Type type) - { - emitter.Emit(OpCodes.Castclass, type); - } - - /// - /// Returns from the current method. - /// - /// The target . - public static void Return(this IEmitter emitter) - { - emitter.Emit(OpCodes.Ret); - } - } - - /// - /// An ultra lightweight service container. - /// - [System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage] - internal class ServiceContainer : IServiceContainer - { - private const string UnresolvedDependencyError = "Unresolved dependency {0}"; - private readonly Func methodSkeletonFactory; - private readonly ServiceRegistry> emitters = new ServiceRegistry>(); - private readonly object lockObject = new object(); - - private readonly Storage constants = new Storage(); - - private readonly Storage factoryRules = new Storage(); - private readonly Stack> dependencyStack = new Stack>(); - - private readonly ServiceRegistry availableServices = new ServiceRegistry(); - - private readonly Storage decorators = new Storage(); - private readonly Storage overrides = new Storage(); - - private readonly Lazy constructionInfoProvider; - private readonly ICompositionRootExecutor compositionRootExecutor; - - private readonly ITypeExtractor compositionRootTypeExtractor; - private ImmutableHashTree> delegates = - ImmutableHashTree>.Empty; - - private ImmutableHashTree, Func> namedDelegates = - ImmutableHashTree, Func>.Empty; - - private ImmutableHashTree> propertyInjectionDelegates = - ImmutableHashTree>.Empty; - - private bool isLocked; - - /// - /// Initializes a new instance of the class. - /// - public ServiceContainer() - { - var concreteTypeExtractor = new CachedTypeExtractor(new ConcreteTypeExtractor()); - compositionRootTypeExtractor = new CachedTypeExtractor(new CompositionRootTypeExtractor()); - compositionRootExecutor = new CompositionRootExecutor(this); - AssemblyScanner = new AssemblyScanner(concreteTypeExtractor, compositionRootTypeExtractor, compositionRootExecutor); - PropertyDependencySelector = new PropertyDependencySelector(new PropertySelector()); - ConstructorDependencySelector = new ConstructorDependencySelector(); - ConstructorSelector = new MostResolvableConstructorSelector(CanGetInstance); - constructionInfoProvider = new Lazy(CreateConstructionInfoProvider); - methodSkeletonFactory = (returnType, parameterTypes) => new DynamicMethodSkeleton(returnType, parameterTypes); - ScopeManagerProvider = new PerThreadScopeManagerProvider(); - AssemblyLoader = new AssemblyLoader(); - } - - /// - /// Gets or sets the that is responsible - /// for providing the used to manage scopes. - /// - public IScopeManagerProvider ScopeManagerProvider { get; set; } - - /// - /// Gets or sets the instance that - /// is responsible for selecting the property dependencies for a given type. - /// - public IPropertyDependencySelector PropertyDependencySelector { get; set; } - - /// - /// Gets or sets the instance that - /// is responsible for selecting the constructor dependencies for a given constructor. - /// - public IConstructorDependencySelector ConstructorDependencySelector { get; set; } - - /// - /// Gets or sets the instance that is responsible - /// for selecting the constructor to be used when creating new service instances. - /// - public IConstructorSelector ConstructorSelector { get; set; } - - /// - /// Gets or sets the instance that is responsible for scanning assemblies. - /// - public IAssemblyScanner AssemblyScanner { get; set; } - - /// - /// Gets or sets the instance that is responsible for loading assemblies during assembly scanning. - /// - public IAssemblyLoader AssemblyLoader { get; set; } - - /// - /// Gets a list of instances that represents the registered services. - /// - public IEnumerable AvailableServices - { - get - { - return availableServices.Values.SelectMany(t => t.Values); - } - } - - /// - /// Returns true if the container can create the requested service, otherwise false. - /// - /// The of the service. - /// The name of the service. - /// true if the container can create the requested service, otherwise false. - public bool CanGetInstance(Type serviceType, string serviceName) - { - return GetEmitMethod(serviceType, serviceName) != null; - } - - /// - /// Starts a new . - /// - /// - public Scope BeginScope() - { - return ScopeManagerProvider.GetScopeManager().BeginScope(); - } - - /// - /// Ends the current . - /// - public void EndCurrentScope() - { - Scope currentScope = ScopeManagerProvider.GetScopeManager().CurrentScope; - currentScope.Dispose(); - } - - /// - /// Injects the property dependencies for a given . - /// - /// The target instance for which to inject its property dependencies. - /// The with its property dependencies injected. - public object InjectProperties(object instance) - { - var type = instance.GetType(); - - var del = propertyInjectionDelegates.Search(type); - - if (del == null) - { - del = CreatePropertyInjectionDelegate(type); - propertyInjectionDelegates = propertyInjectionDelegates.Add(type, del); - } - - return del(constants.Items, instance); - } - - /// - /// Registers the with the that - /// describes the dependencies of the service. - /// - /// The service type to register. - /// The lambdaExpression that describes the dependencies of the service. - /// The name of the service. - /// The instance that controls the lifetime of the registered service. - public void Register(Expression> factory, string serviceName, ILifetime lifetime) - { - RegisterServiceFromLambdaExpression(factory, lifetime, serviceName); - } - - /// - /// Registers a custom factory delegate used to create services that is otherwise unknown to the service container. - /// - /// Determines if the service can be created by the delegate. - /// Creates a service instance according to the predicate. - public void RegisterFallback(Func predicate, Func factory) - { - factoryRules.Add(new FactoryRule { CanCreateInstance = predicate, Factory = factory }); - } - - /// - /// Registers a custom factory delegate used to create services that is otherwise unknown to the service container. - /// - /// Determines if the service can be created by the delegate. - /// Creates a service instance according to the predicate. - /// The instance that controls the lifetime of the registered service. - public void RegisterFallback(Func predicate, Func factory, ILifetime lifetime) - { - factoryRules.Add(new FactoryRule { CanCreateInstance = predicate, Factory = factory, LifeTime = lifetime }); - } - - /// - /// Registers a service based on a instance. - /// - /// The instance that contains service metadata. - public void Register(ServiceRegistration serviceRegistration) - { - var services = GetAvailableServices(serviceRegistration.ServiceType); - var sr = serviceRegistration; - services.AddOrUpdate( - serviceRegistration.ServiceName, - s => AddServiceRegistration(sr), - (k, existing) => UpdateServiceRegistration(existing, sr)); - } - - /// - /// Registers composition roots from the given . - /// - /// The assembly to be scanned for services. - /// - /// If the target contains an implementation of the interface, this - /// will be used to configure the container. - /// - public void RegisterAssembly(Assembly assembly) - { - Type[] compositionRootTypes = compositionRootTypeExtractor.Execute(assembly); - if (compositionRootTypes.Length == 0) - { - RegisterAssembly(assembly, (serviceType, implementingType) => true); - } - else - { - AssemblyScanner.Scan(assembly, this); - } - } - - /// - /// Registers services from the given . - /// - /// The assembly to be scanned for services. - /// A function delegate that determines if a service implementation should be registered. - /// - /// If the target contains an implementation of the interface, this - /// will be used to configure the container. - /// - public void RegisterAssembly(Assembly assembly, Func shouldRegister) - { - AssemblyScanner.Scan(assembly, this, () => null, shouldRegister); - } - - /// - /// Registers services from the given . - /// - /// The assembly to be scanned for services. - /// The factory that controls the lifetime of the registered service. - /// - /// If the target contains an implementation of the interface, this - /// will be used to configure the container. - /// - public void RegisterAssembly(Assembly assembly, Func lifetimeFactory) - { - AssemblyScanner.Scan(assembly, this, lifetimeFactory, (serviceType, implementingType) => true); - } - - /// - /// Registers services from the given . - /// - /// The assembly to be scanned for services. - /// The factory that controls the lifetime of the registered service. - /// A function delegate that determines if a service implementation should be registered. - /// - /// If the target contains an implementation of the interface, this - /// will be used to configure the container. - /// - public void RegisterAssembly(Assembly assembly, Func lifetimeFactory, Func shouldRegister) - { - AssemblyScanner.Scan(assembly, this, lifetimeFactory, shouldRegister); - } - - /// - /// Registers services from the given type. - /// - /// The type of to register from. - public void RegisterFrom() where TCompositionRoot : ICompositionRoot, new() - { - compositionRootExecutor.Execute(typeof(TCompositionRoot)); - } - - /// - /// Registers composition roots from assemblies in the base directory that matches the . - /// - /// The search pattern used to filter the assembly files. - public void RegisterAssembly(string searchPattern) - { - foreach (Assembly assembly in AssemblyLoader.Load(searchPattern)) - { - RegisterAssembly(assembly); - } - } - - /// - /// Decorates the with the given . - /// - /// The target service type. - /// The decorator type used to decorate the . - /// A function delegate that determines if the - /// should be applied to the target . - public void Decorate(Type serviceType, Type decoratorType, Func predicate) - { - var decoratorRegistration = new DecoratorRegistration { ServiceType = serviceType, ImplementingType = decoratorType, CanDecorate = predicate }; - Decorate(decoratorRegistration); - } - - /// - /// Decorates the with the given . - /// - /// The target service type. - /// The decorator type used to decorate the . - public void Decorate(Type serviceType, Type decoratorType) - { - Decorate(serviceType, decoratorType, si => true); - } - - /// - /// Decorates the with the given . - /// - /// The target service type. - /// The decorator type used to decorate the . - public void Decorate() where TDecorator : TService - { - Decorate(typeof(TService), typeof(TDecorator)); - } - - /// - /// Decorates the using the given decorator . - /// - /// The target service type. - /// A factory delegate used to create a decorator instance. - public void Decorate(Expression> factory) - { - var decoratorRegistration = new DecoratorRegistration { FactoryExpression = factory, ServiceType = typeof(TService), CanDecorate = si => true }; - Decorate(decoratorRegistration); - } - - /// - /// Registers a decorator based on a instance. - /// - /// The instance that contains the decorator metadata. - public void Decorate(DecoratorRegistration decoratorRegistration) - { - int index = decorators.Add(decoratorRegistration); - decoratorRegistration.Index = index; - } - - /// - /// Allows a registered service to be overridden by another . - /// - /// A function delegate that is used to determine the service that should be - /// overridden using the returned from the . - /// The factory delegate used to create a that overrides - /// the incoming . - public void Override(Func serviceSelector, Func serviceRegistrationFactory) - { - var serviceOverride = new ServiceOverride - { - CanOverride = serviceSelector, - ServiceRegistrationFactory = serviceRegistrationFactory - }; - overrides.Add(serviceOverride); - } - - /// - /// Registers the with the . - /// - /// The service type to register. - /// The implementing type. - /// The instance that controls the lifetime of the registered service. - public void Register(Type serviceType, Type implementingType, ILifetime lifetime) - { - Register(serviceType, implementingType, string.Empty, lifetime); - } - - /// - /// Registers the with the . - /// - /// The service type to register. - /// The implementing type. - /// The name of the service. - /// The instance that controls the lifetime of the registered service. - public void Register(Type serviceType, Type implementingType, string serviceName, ILifetime lifetime) - { - RegisterService(serviceType, implementingType, lifetime, serviceName); - } - - /// - /// Registers the with the . - /// - /// The service type to register. - /// The implementing type. - public void Register() where TImplementation : TService - { - Register(typeof(TService), typeof(TImplementation)); - } - - /// - /// Registers the with the . - /// - /// The service type to register. - /// The implementing type. - /// The instance that controls the lifetime of the registered service. - public void Register(ILifetime lifetime) where TImplementation : TService - { - Register(typeof(TService), typeof(TImplementation), lifetime); - } - - /// - /// Registers the with the . - /// - /// The service type to register. - /// The implementing type. - /// The name of the service. - public void Register(string serviceName) where TImplementation : TService - { - Register(serviceName, lifetime: null); - } - - /// - /// Registers the with the . - /// - /// The service type to register. - /// The implementing type. - /// The name of the service. - /// The instance that controls the lifetime of the registered service. - public void Register(string serviceName, ILifetime lifetime) where TImplementation : TService - { - Register(typeof(TService), typeof(TImplementation), serviceName, lifetime); - } - - /// - /// Registers the with the that - /// describes the dependencies of the service. - /// - /// The service type to register. - /// The lambdaExpression that describes the dependencies of the service. - /// The instance that controls the lifetime of the registered service. - public void Register(Expression> factory, ILifetime lifetime) - { - RegisterServiceFromLambdaExpression(factory, lifetime, string.Empty); - } - - /// - /// Registers the with the that - /// describes the dependencies of the service. - /// - /// The service type to register. - /// The lambdaExpression that describes the dependencies of the service. - /// The name of the service. - public void Register(Expression> factory, string serviceName) - { - RegisterServiceFromLambdaExpression(factory, null, serviceName); - } - - /// - /// Registers a concrete type as a service. - /// - /// The service type to register. - public void Register() - { - Register(); - } - - /// - /// Registers a concrete type as a service. - /// - /// The concrete type to register. - public void Register(Type serviceType) - { - Register(serviceType, serviceType); - } - - /// - /// Registers a concrete type as a service. - /// - /// The concrete type to register. - /// The instance that controls the lifetime of the registered service. - public void Register(Type serviceType, ILifetime lifetime) - { - Register(serviceType, serviceType, lifetime); - } - - /// - /// Registers a concrete type as a service. - /// - /// The service type to register. - /// The instance that controls the lifetime of the registered service. - public void Register(ILifetime lifetime) - { - Register(lifetime); - } - - /// - /// Registers the with the given . - /// - /// The service type to register. - /// The instance returned when this service is requested. - /// The name of the service. - public void RegisterInstance(TService instance, string serviceName) - { - RegisterInstance(typeof(TService), instance, serviceName); - } - - /// - /// Registers the with the given . - /// - /// The service type to register. - /// The instance returned when this service is requested. - public void RegisterInstance(TService instance) - { - RegisterInstance(typeof(TService), instance); - } - - /// - /// Registers the with the given . - /// - /// The service type to register. - /// The instance returned when this service is requested. - public void RegisterInstance(Type serviceType, object instance) - { - RegisterInstance(serviceType, instance, string.Empty); - } - - /// - /// Registers the with the given . - /// - /// The service type to register. - /// The instance returned when this service is requested. - /// The name of the service. - public void RegisterInstance(Type serviceType, object instance, string serviceName) - { - RegisterValue(serviceType, instance, serviceName); - } - - /// - /// Registers the with the that - /// describes the dependencies of the service. - /// - /// The service type to register. - /// The lambdaExpression that describes the dependencies of the service. - public void Register(Expression> factory) - { - RegisterServiceFromLambdaExpression(factory, null, string.Empty); - } - - /// - /// Registers the with the that - /// describes the dependencies of the service. - /// - /// The parameter type. - /// The service type to register. - /// A factory delegate used to create the instance. - public void Register(Expression> factory) - { - RegisterServiceFromLambdaExpression(factory, null, string.Empty); - } - - /// - /// Registers the with the that - /// describes the dependencies of the service. - /// - /// The parameter type. - /// The service type to register. - /// A factory delegate used to create the instance. - /// The name of the service. - public void Register(Expression> factory, string serviceName) - { - RegisterServiceFromLambdaExpression(factory, null, serviceName); - } - - /// - /// Registers the with the that - /// describes the dependencies of the service. - /// - /// The type of the first parameter. - /// The type of the second parameter. - /// The service type to register. - /// A factory delegate used to create the instance. - public void Register(Expression> factory) - { - RegisterServiceFromLambdaExpression(factory, null, string.Empty); - } - - /// - /// Registers the with the that - /// describes the dependencies of the service. - /// - /// The type of the first parameter. - /// The type of the second parameter. - /// The service type to register. - /// A factory delegate used to create the instance. - /// The name of the service. - public void Register(Expression> factory, string serviceName) - { - RegisterServiceFromLambdaExpression(factory, null, serviceName); - } - - /// - /// Registers the with the that - /// describes the dependencies of the service. - /// - /// The type of the first parameter. - /// The type of the second parameter. - /// The type of the third parameter. - /// The service type to register. - /// A factory delegate used to create the instance. - public void Register(Expression> factory) - { - RegisterServiceFromLambdaExpression(factory, null, string.Empty); - } - - /// - /// Registers the with the that - /// describes the dependencies of the service. - /// - /// The type of the first parameter. - /// The type of the second parameter. - /// The type of the third parameter. - /// The service type to register. - /// A factory delegate used to create the instance. - /// The name of the service. - public void Register(Expression> factory, string serviceName) - { - RegisterServiceFromLambdaExpression(factory, null, serviceName); - } - - /// - /// Registers the with the that - /// describes the dependencies of the service. - /// - /// The type of the first parameter. - /// The type of the second parameter. - /// The type of the third parameter. - /// The type of the fourth parameter. - /// The service type to register. - /// A factory delegate used to create the instance. - public void Register(Expression> factory) - { - RegisterServiceFromLambdaExpression(factory, null, string.Empty); - } - - /// - /// Registers the with the that - /// describes the dependencies of the service. - /// - /// The type of the first parameter. - /// The type of the second parameter. - /// The type of the third parameter. - /// The type of the fourth parameter. - /// The service type to register. - /// A factory delegate used to create the instance. - /// The name of the service. - public void Register(Expression> factory, string serviceName) - { - RegisterServiceFromLambdaExpression(factory, null, serviceName); - } - - /// - /// Registers the with the . - /// - /// The service type to register. - /// The implementing type. - /// The name of the service. - public void Register(Type serviceType, Type implementingType, string serviceName) - { - RegisterService(serviceType, implementingType, null, serviceName); - } - - /// - /// Registers the with the . - /// - /// The service type to register. - /// The implementing type. - public void Register(Type serviceType, Type implementingType) - { - RegisterService(serviceType, implementingType, null, string.Empty); - } - - /// - /// Gets an instance of the given . - /// - /// The type of the requested service. - /// The requested service instance. - public object GetInstance(Type serviceType) - { - var instanceDelegate = delegates.Search(serviceType); - if (instanceDelegate == null) - { - instanceDelegate = CreateDefaultDelegate(serviceType, throwError: true); - } - - return instanceDelegate(constants.Items); - } - - /// - /// Gets an instance of the given . - /// - /// The type of the requested service. - /// The arguments to be passed to the target instance. - /// The requested service instance. - public object GetInstance(Type serviceType, object[] arguments) - { - var instanceDelegate = delegates.Search(serviceType); - if (instanceDelegate == null) - { - instanceDelegate = CreateDefaultDelegate(serviceType, throwError: true); - } - - object[] constantsWithArguments = constants.Items.Concat(new object[] { arguments }).ToArray(); - - return instanceDelegate(constantsWithArguments); - } - - /// - /// Gets an instance of the given . - /// - /// The type of the requested service. - /// The name of the requested service. - /// The arguments to be passed to the target instance. - /// The requested service instance. - public object GetInstance(Type serviceType, string serviceName, object[] arguments) - { - var key = Tuple.Create(serviceType, serviceName); - var instanceDelegate = namedDelegates.Search(key); - if (instanceDelegate == null) - { - instanceDelegate = CreateNamedDelegate(key, throwError: true); - } - - object[] constantsWithArguments = constants.Items.Concat(new object[] { arguments }).ToArray(); - - return instanceDelegate(constantsWithArguments); - } - - /// - /// Gets an instance of the given type. - /// - /// The type of the requested service. - /// The requested service instance. - public TService GetInstance() - { - return (TService)GetInstance(typeof(TService)); - } - - /// - /// Gets a named instance of the given . - /// - /// The type of the requested service. - /// The name of the requested service. - /// The requested service instance. - public TService GetInstance(string serviceName) - { - return (TService)GetInstance(typeof(TService), serviceName); - } - - /// - /// Gets an instance of the given . - /// - /// The type of the argument. - /// The type of the requested service. - /// The argument value. - /// The requested service instance. - public TService GetInstance(T value) - { - return (TService)GetInstance(typeof(TService), new object[] { value }); - } - - /// - /// Gets an instance of the given . - /// - /// The type of the parameter. - /// The type of the requested service. - /// The argument value. - /// The name of the requested service. - /// The requested service instance. - public TService GetInstance(T value, string serviceName) - { - return (TService)GetInstance(typeof(TService), serviceName, new object[] { value }); - } - - /// - /// Gets an instance of the given . - /// - /// The type of the first parameter. - /// The type of the second parameter. - /// The type of the requested service. - /// The first argument value. - /// The second argument value. - /// The requested service instance. - public TService GetInstance(T1 arg1, T2 arg2) - { - return (TService)GetInstance(typeof(TService), new object[] { arg1, arg2 }); - } - - /// - /// Gets an instance of the given . - /// - /// The type of the first parameter. - /// The type of the second parameter. - /// The type of the requested service. - /// The first argument value. - /// The second argument value. - /// The name of the requested service. - /// The requested service instance. - public TService GetInstance(T1 arg1, T2 arg2, string serviceName) - { - return (TService)GetInstance(typeof(TService), serviceName, new object[] { arg1, arg2 }); - } - - /// - /// Gets an instance of the given . - /// - /// The type of the first parameter. - /// The type of the second parameter. - /// The type of the third parameter. - /// The type of the requested service. - /// The first argument value. - /// The second argument value. - /// The third argument value. - /// The requested service instance. - public TService GetInstance(T1 arg1, T2 arg2, T3 arg3) - { - return (TService)GetInstance(typeof(TService), new object[] { arg1, arg2, arg3 }); - } - - /// - /// Gets an instance of the given . - /// - /// The type of the first parameter. - /// The type of the second parameter. - /// The type of the third parameter. - /// The type of the requested service. - /// The first argument value. - /// The second argument value. - /// The third argument value. - /// The name of the requested service. - /// The requested service instance. - public TService GetInstance(T1 arg1, T2 arg2, T3 arg3, string serviceName) - { - return (TService)GetInstance(typeof(TService), serviceName, new object[] { arg1, arg2, arg3 }); - } - - /// - /// Gets an instance of the given . - /// - /// The type of the first parameter. - /// The type of the second parameter. - /// The type of the third parameter. - /// The type of the fourth parameter. - /// The type of the requested service. - /// The first argument value. - /// The second argument value. - /// The third argument value. - /// The fourth argument value. - /// The requested service instance. - public TService GetInstance(T1 arg1, T2 arg2, T3 arg3, T4 arg4) - { - return (TService)GetInstance(typeof(TService), new object[] { arg1, arg2, arg3, arg4 }); - } - - /// - /// Gets an instance of the given . - /// - /// The type of the first parameter. - /// The type of the second parameter. - /// The type of the third parameter. - /// The type of the fourth parameter. - /// The type of the requested service. - /// The first argument value. - /// The second argument value. - /// The third argument value. - /// The fourth argument value. - /// The name of the requested service. - /// The requested service instance. - public TService GetInstance(T1 arg1, T2 arg2, T3 arg3, T4 arg4, string serviceName) - { - return (TService)GetInstance(typeof(TService), serviceName, new object[] { arg1, arg2, arg3, arg4 }); - } - - /// - /// Gets an instance of the given . - /// - /// The type of the requested service. - /// The requested service instance if available, otherwise null. - public object TryGetInstance(Type serviceType) - { - var instanceDelegate = delegates.Search(serviceType); - if (instanceDelegate == null) - { - instanceDelegate = CreateDefaultDelegate(serviceType, throwError: false); - } - - return instanceDelegate(constants.Items); - } - - /// - /// Gets a named instance of the given . - /// - /// The type of the requested service. - /// The name of the requested service. - /// The requested service instance if available, otherwise null. - public object TryGetInstance(Type serviceType, string serviceName) - { - var key = Tuple.Create(serviceType, serviceName); - var instanceDelegate = namedDelegates.Search(key); - if (instanceDelegate == null) - { - instanceDelegate = CreateNamedDelegate(key, throwError: false); - } - - return instanceDelegate(constants.Items); - } - - /// - /// Tries to get an instance of the given type. - /// - /// The type of the requested service. - /// The requested service instance if available, otherwise default(T). - public TService TryGetInstance() - { - return (TService)TryGetInstance(typeof(TService)); - } - - /// - /// Tries to get an instance of the given type. - /// - /// The type of the requested service. - /// The name of the requested service. - /// The requested service instance if available, otherwise default(T). - public TService TryGetInstance(string serviceName) - { - return (TService)TryGetInstance(typeof(TService), serviceName); - } - - /// - /// Gets a named instance of the given . - /// - /// The type of the requested service. - /// The name of the requested service. - /// The requested service instance. - public object GetInstance(Type serviceType, string serviceName) - { - var key = Tuple.Create(serviceType, serviceName); - var instanceDelegate = namedDelegates.Search(key); - if (instanceDelegate == null) - { - instanceDelegate = CreateNamedDelegate(key, throwError: true); - } - - return instanceDelegate(constants.Items); - } - - /// - /// Gets all instances of the given . - /// - /// The type of services to resolve. - /// A list that contains all implementations of the . - public IEnumerable GetAllInstances(Type serviceType) - { - return (IEnumerable)GetInstance(serviceType.GetEnumerableType()); - } - - /// - /// Gets all instances of type . - /// - /// The type of services to resolve. - /// A list that contains all implementations of the type. - public IEnumerable GetAllInstances() - { - return GetInstance>(); - } - - /// - /// Creates an instance of a concrete class. - /// - /// The type of class for which to create an instance. - /// An instance of . - /// The concrete type will be registered if not already registered with the container. - public TService Create() where TService : class - { - Register(typeof(TService)); - return GetInstance(); - } - - /// - /// Creates an instance of a concrete class. - /// - /// The type of class for which to create an instance. - /// An instance of the . - public object Create(Type serviceType) - { - Register(serviceType); - return GetInstance(serviceType); - } - - /// - /// Disposes any services registered using the . - /// - public void Dispose() - { - var disposableLifetimeInstances = availableServices.Values.SelectMany(t => t.Values) - .Where(sr => sr.Lifetime != null) - .Select(sr => sr.Lifetime) - .Where(lt => lt is IDisposable).Cast(); - foreach (var disposableLifetimeInstance in disposableLifetimeInstances) - { - disposableLifetimeInstance.Dispose(); - } - } - - /// - /// Invalidates the container and causes the compiler to "recompile". - /// - public void Invalidate() - { - Interlocked.Exchange(ref delegates, ImmutableHashTree>.Empty); - Interlocked.Exchange(ref namedDelegates, ImmutableHashTree, Func>.Empty); - Interlocked.Exchange(ref propertyInjectionDelegates, ImmutableHashTree>.Empty); - constants.Clear(); - constructionInfoProvider.Value.Invalidate(); - isLocked = false; - } - - private static void EmitNewArray(IList> emitMethods, Type elementType, IEmitter emitter) - { - LocalBuilder array = emitter.DeclareLocal(elementType.MakeArrayType()); - emitter.Push(emitMethods.Count); - emitter.PushNewArray(elementType); - emitter.Store(array); - - for (int index = 0; index < emitMethods.Count; index++) - { - emitter.Push(array); - emitter.Push(index); - emitMethods[index](emitter); - emitter.UnboxOrCast(elementType); - emitter.Emit(OpCodes.Stelem, elementType); - } - - emitter.Push(array); - } - - private static ILifetime CloneLifeTime(ILifetime lifetime) - { - return lifetime == null ? null : (ILifetime)Activator.CreateInstance(lifetime.GetType()); - } - - private static ConstructorDependency GetConstructorDependencyThatRepresentsDecoratorTarget( - DecoratorRegistration decoratorRegistration, ConstructionInfo constructionInfo) - { - var constructorDependency = - constructionInfo.ConstructorDependencies.FirstOrDefault( - cd => - cd.ServiceType == decoratorRegistration.ServiceType - || (cd.ServiceType.IsLazy() - && cd.ServiceType.GetGenericTypeArguments()[0] == decoratorRegistration.ServiceType)); - return constructorDependency; - } - - private static DecoratorRegistration CreateClosedGenericDecoratorRegistration( - ServiceRegistration serviceRegistration, DecoratorRegistration openGenericDecorator) - { - Type implementingType = openGenericDecorator.ImplementingType; - Type[] genericTypeArguments = serviceRegistration.ServiceType.GetGenericTypeArguments(); - Type closedGenericDecoratorType = implementingType.MakeGenericType(genericTypeArguments); - - var decoratorInfo = new DecoratorRegistration - { - ServiceType = serviceRegistration.ServiceType, - ImplementingType = closedGenericDecoratorType, - CanDecorate = openGenericDecorator.CanDecorate, - Index = openGenericDecorator.Index - }; - return decoratorInfo; - } - - private static Type TryMakeGenericType(Type implementingType, Type[] closedGenericArguments) - { - try - { - return implementingType.MakeGenericType(closedGenericArguments); - } - catch (Exception) - { - return null; - } - } - - private void EmitEnumerable(IList> serviceEmitters, Type elementType, IEmitter emitter) - { - EmitNewArray(serviceEmitters, elementType, emitter); - } - - private Func CreatePropertyInjectionDelegate(Type concreteType) - { - lock (lockObject) - { - IMethodSkeleton methodSkeleton = methodSkeletonFactory(typeof(object), new[] { typeof(object[]), typeof(object) }); - ConstructionInfo constructionInfo = GetContructionInfoForConcreteType(concreteType); - var emitter = methodSkeleton.GetEmitter(); - emitter.PushArgument(1); - emitter.Cast(concreteType); - try - { - EmitPropertyDependencies(constructionInfo, emitter); - } - catch (Exception) - { - dependencyStack.Clear(); - throw; - } - - emitter.Return(); - - isLocked = true; - - return (Func)methodSkeleton.CreateDelegate(typeof(Func)); - } - } - - private ConstructionInfo GetContructionInfoForConcreteType(Type concreteType) - { - var serviceRegistration = GetServiceRegistrationForConcreteType(concreteType); - return GetConstructionInfo(serviceRegistration); - } - - private ServiceRegistration GetServiceRegistrationForConcreteType(Type concreteType) - { - var services = GetAvailableServices(concreteType); - return services.GetOrAdd(string.Empty, s => CreateServiceRegistrationBasedOnConcreteType(concreteType)); - } - - private ServiceRegistration CreateServiceRegistrationBasedOnConcreteType(Type type) - { - var serviceRegistration = new ServiceRegistration - { - ServiceType = type, - ImplementingType = type, - ServiceName = string.Empty, - IgnoreConstructorDependencies = true - }; - return serviceRegistration; - } - - private ConstructionInfoProvider CreateConstructionInfoProvider() - { - return new ConstructionInfoProvider(CreateConstructionInfoBuilder()); - } - - private ConstructionInfoBuilder CreateConstructionInfoBuilder() - { - return new ConstructionInfoBuilder(() => new LambdaConstructionInfoBuilder(), CreateTypeConstructionInfoBuilder); - } - - private TypeConstructionInfoBuilder CreateTypeConstructionInfoBuilder() - { - return new TypeConstructionInfoBuilder(ConstructorSelector, ConstructorDependencySelector, PropertyDependencySelector); - } - - private Func CreateDynamicMethodDelegate(Action serviceEmitter) - { - var methodSkeleton = methodSkeletonFactory(typeof(object), new[] { typeof(object[]) }); - IEmitter emitter = methodSkeleton.GetEmitter(); - serviceEmitter(emitter); - if (emitter.StackType.IsValueType()) - { - emitter.Emit(OpCodes.Box, emitter.StackType); - } - - Instruction lastInstruction = emitter.Instructions.Last(); - - if (lastInstruction.Code == OpCodes.Castclass) - { - emitter.Instructions.Remove(lastInstruction); - } - - emitter.Return(); - - isLocked = true; - - return (Func)methodSkeleton.CreateDelegate(typeof(Func)); - } - - private Func WrapAsFuncDelegate(Func instanceDelegate) - { - return () => instanceDelegate(constants.Items); - } - - private Action GetEmitMethod(Type serviceType, string serviceName) - { - Action emitMethod = GetRegisteredEmitMethod(serviceType, serviceName); - - if (emitMethod == null) - { - emitMethod = TryGetFallbackEmitMethod(serviceType, serviceName); - } - - if (emitMethod == null) - { - AssemblyScanner.Scan(serviceType.GetAssembly(), this); - emitMethod = GetRegisteredEmitMethod(serviceType, serviceName); - } - - if (emitMethod == null) - { - emitMethod = TryGetFallbackEmitMethod(serviceType, serviceName); - } - - return CreateEmitMethodWrapper(emitMethod, serviceType, serviceName); - } - - private Action TryGetFallbackEmitMethod(Type serviceType, string serviceName) - { - Action emitMethod = null; - var rule = factoryRules.Items.FirstOrDefault(r => r.CanCreateInstance(serviceType, serviceName)); - if (rule != null) - { - emitMethod = CreateServiceEmitterBasedOnFactoryRule(rule, serviceType, serviceName); - UpdateEmitMethod(serviceType, serviceName, emitMethod); - } - - return emitMethod; - } - - private Action CreateEmitMethodWrapper(Action emitter, Type serviceType, string serviceName) - { - if (emitter == null) - { - return null; - } - - return ms => - { - if (dependencyStack.Contains(emitter)) - { - throw new InvalidOperationException( - string.Format("Recursive dependency detected: ServiceType:{0}, ServiceName:{1}]", serviceType, serviceName)); - } - - dependencyStack.Push(emitter); - try - { - emitter(ms); - } - finally - { - if (dependencyStack.Count > 0) - { - dependencyStack.Pop(); - } - } - }; - } - - private Action GetRegisteredEmitMethod(Type serviceType, string serviceName) - { - Action emitMethod; - var registrations = GetEmitMethods(serviceType); - registrations.TryGetValue(serviceName, out emitMethod); - return emitMethod ?? CreateEmitMethodForUnknownService(serviceType, serviceName); - } - - private void UpdateEmitMethod(Type serviceType, string serviceName, Action emitMethod) - { - if (emitMethod != null) - { - GetEmitMethods(serviceType).AddOrUpdate(serviceName, s => emitMethod, (s, m) => emitMethod); - } - } - - private ServiceRegistration AddServiceRegistration(ServiceRegistration serviceRegistration) - { - var emitDelegate = ResolveEmitMethod(serviceRegistration); - GetEmitMethods(serviceRegistration.ServiceType).TryAdd(serviceRegistration.ServiceName, emitDelegate); - return serviceRegistration; - } - - private ServiceRegistration UpdateServiceRegistration(ServiceRegistration existingRegistration, ServiceRegistration newRegistration) - { - if (existingRegistration.IsReadOnly || isLocked) - { - return existingRegistration; - } - - Invalidate(); - Action emitMethod = ResolveEmitMethod(newRegistration); - - var serviceEmitters = GetEmitMethods(newRegistration.ServiceType); - serviceEmitters[newRegistration.ServiceName] = emitMethod; - return newRegistration; - } - - private void EmitNewInstanceWithDecorators(ServiceRegistration serviceRegistration, IEmitter emitter) - { - var serviceOverrides = overrides.Items.Where(so => so.CanOverride(serviceRegistration)).ToArray(); - foreach (var serviceOverride in serviceOverrides) - { - serviceRegistration = serviceOverride.ServiceRegistrationFactory(this, serviceRegistration); - } - - var serviceDecorators = GetDecorators(serviceRegistration); - if (serviceDecorators.Length > 0) - { - EmitDecorators(serviceRegistration, serviceDecorators, emitter, dm => EmitNewInstance(serviceRegistration, dm)); - } - else - { - EmitNewInstance(serviceRegistration, emitter); - } - } - - private DecoratorRegistration[] GetDecorators(ServiceRegistration serviceRegistration) - { - var registeredDecorators = decorators.Items.Where(d => d.ServiceType == serviceRegistration.ServiceType).ToList(); - - registeredDecorators.AddRange(GetOpenGenericDecoratorRegistrations(serviceRegistration)); - registeredDecorators.AddRange(GetDeferredDecoratorRegistrations(serviceRegistration)); - return registeredDecorators.OrderBy(d => d.Index).ToArray(); - } - - private IEnumerable GetOpenGenericDecoratorRegistrations( - ServiceRegistration serviceRegistration) - { - var registrations = new List(); - if (serviceRegistration.ServiceType.IsGenericType()) - { - var openGenericServiceType = serviceRegistration.ServiceType.GetGenericTypeDefinition(); - var openGenericDecorators = decorators.Items.Where(d => d.ServiceType == openGenericServiceType); - registrations.AddRange( - openGenericDecorators.Select( - openGenericDecorator => - CreateClosedGenericDecoratorRegistration(serviceRegistration, openGenericDecorator))); - } - - return registrations; - } - - private IEnumerable GetDeferredDecoratorRegistrations( - ServiceRegistration serviceRegistration) - { - var registrations = new List(); - - var deferredDecorators = - decorators.Items.Where(ds => ds.CanDecorate(serviceRegistration) && ds.HasDeferredImplementingType); - foreach (var deferredDecorator in deferredDecorators) - { - var decoratorRegistration = new DecoratorRegistration - { - ServiceType = serviceRegistration.ServiceType, - ImplementingType = - deferredDecorator.ImplementingTypeFactory(this, serviceRegistration), - CanDecorate = sr => true, - Index = deferredDecorator.Index - }; - registrations.Add(decoratorRegistration); - } - - return registrations; - } - - private void EmitNewDecoratorInstance(DecoratorRegistration decoratorRegistration, IEmitter emitter, Action pushInstance) - { - ConstructionInfo constructionInfo = GetConstructionInfo(decoratorRegistration); - var constructorDependency = GetConstructorDependencyThatRepresentsDecoratorTarget( - decoratorRegistration, constructionInfo); - - if (constructorDependency != null) - { - constructorDependency.IsDecoratorTarget = true; - } - - if (constructionInfo.FactoryDelegate != null) - { - EmitNewDecoratorUsingFactoryDelegate(constructionInfo.FactoryDelegate, emitter, pushInstance); - } - else - { - EmitNewInstanceUsingImplementingType(emitter, constructionInfo, pushInstance); - } - } - - private void EmitNewDecoratorUsingFactoryDelegate(Delegate factoryDelegate, IEmitter emitter, Action pushInstance) - { - var factoryDelegateIndex = constants.Add(factoryDelegate); - var serviceFactoryIndex = constants.Add(this); - Type funcType = factoryDelegate.GetType(); - emitter.PushConstant(factoryDelegateIndex, funcType); - emitter.PushConstant(serviceFactoryIndex, typeof(IServiceFactory)); - pushInstance(emitter); - MethodInfo invokeMethod = funcType.GetMethod("Invoke"); - emitter.Emit(OpCodes.Callvirt, invokeMethod); - } - - private void EmitNewInstance(ServiceRegistration serviceRegistration, IEmitter emitter) - { - if (serviceRegistration.Value != null) - { - int index = constants.Add(serviceRegistration.Value); - Type serviceType = serviceRegistration.ServiceType; - emitter.PushConstant(index, serviceType); - } - else - { - var constructionInfo = GetConstructionInfo(serviceRegistration); - - if (constructionInfo.FactoryDelegate != null) - { - EmitNewInstanceUsingFactoryDelegate(constructionInfo.FactoryDelegate, emitter); - } - else - { - EmitNewInstanceUsingImplementingType(emitter, constructionInfo, null); - } - } - } - - private void EmitDecorators(ServiceRegistration serviceRegistration, IEnumerable serviceDecorators, IEmitter emitter, Action decoratorTargetEmitMethod) - { - foreach (DecoratorRegistration decorator in serviceDecorators) - { - if (!decorator.CanDecorate(serviceRegistration)) - { - continue; - } - - Action currentDecoratorTargetEmitter = decoratorTargetEmitMethod; - DecoratorRegistration currentDecorator = decorator; - decoratorTargetEmitMethod = e => EmitNewDecoratorInstance(currentDecorator, e, currentDecoratorTargetEmitter); - } - - decoratorTargetEmitMethod(emitter); - } - - private void EmitNewInstanceUsingImplementingType(IEmitter emitter, ConstructionInfo constructionInfo, Action decoratorTargetEmitMethod) - { - EmitConstructorDependencies(constructionInfo, emitter, decoratorTargetEmitMethod); - emitter.Emit(OpCodes.Newobj, constructionInfo.Constructor); - EmitPropertyDependencies(constructionInfo, emitter); - } - - private void EmitNewInstanceUsingFactoryDelegate(Delegate factoryDelegate, IEmitter emitter) - { - var factoryDelegateIndex = constants.Add(factoryDelegate); - var serviceFactoryIndex = constants.Add(this); - Type funcType = factoryDelegate.GetType(); - emitter.PushConstant(factoryDelegateIndex, funcType); - emitter.PushConstant(serviceFactoryIndex, typeof(IServiceFactory)); - if (factoryDelegate.GetMethodInfo().GetParameters().Length > 2) - { - var parameters = factoryDelegate.GetMethodInfo().GetParameters().Skip(2).ToArray(); - emitter.PushArguments(parameters); - } - - MethodInfo invokeMethod = funcType.GetMethod("Invoke"); - emitter.Call(invokeMethod); - } - - private void EmitConstructorDependencies(ConstructionInfo constructionInfo, IEmitter emitter, Action decoratorTargetEmitter) - { - foreach (ConstructorDependency dependency in constructionInfo.ConstructorDependencies) - { - if (!dependency.IsDecoratorTarget) - { - EmitConstructorDependency(emitter, dependency); - } - else - { - if (dependency.ServiceType.IsLazy()) - { - Action instanceEmitter = decoratorTargetEmitter; - decoratorTargetEmitter = CreateEmitMethodBasedOnLazyServiceRequest( - dependency.ServiceType, t => CreateTypedInstanceDelegate(instanceEmitter, t)); - } - - decoratorTargetEmitter(emitter); - } - } - } - - private Delegate CreateTypedInstanceDelegate(Action emitter, Type serviceType) - { - var openGenericMethod = GetType().GetPrivateMethod("CreateGenericDynamicMethodDelegate"); - var closedGenericMethod = openGenericMethod.MakeGenericMethod(serviceType); - var del = WrapAsFuncDelegate(CreateDynamicMethodDelegate(emitter)); - return (Delegate)closedGenericMethod.Invoke(this, new object[] { del }); - } - - // ReSharper disable UnusedMember.Local - private Func CreateGenericDynamicMethodDelegate(Func del) - // ReSharper restore UnusedMember.Local - { - return () => (T)del(); - } - - private void EmitConstructorDependency(IEmitter emitter, Dependency dependency) - { - var emitMethod = GetEmitMethodForDependency(dependency); - - try - { - emitMethod(emitter); - emitter.UnboxOrCast(dependency.ServiceType); - } - catch (InvalidOperationException ex) - { - throw new InvalidOperationException(string.Format(UnresolvedDependencyError, dependency), ex); - } - } - - private void EmitPropertyDependency(IEmitter emitter, PropertyDependency propertyDependency, LocalBuilder instanceVariable) - { - var propertyDependencyEmitMethod = GetEmitMethodForDependency(propertyDependency); - - if (propertyDependencyEmitMethod == null) - { - return; - } - - emitter.Push(instanceVariable); - propertyDependencyEmitMethod(emitter); - emitter.UnboxOrCast(propertyDependency.ServiceType); - emitter.Call(propertyDependency.Property.GetSetMethod()); - } - - private Action GetEmitMethodForDependency(Dependency dependency) - { - if (dependency.FactoryExpression != null) - { - return skeleton => EmitDependencyUsingFactoryExpression(skeleton, dependency); - } - - Action emitter = GetEmitMethod(dependency.ServiceType, dependency.ServiceName); - if (emitter == null) - { - emitter = GetEmitMethod(dependency.ServiceType, dependency.Name); - if (emitter == null && dependency.IsRequired) - { - throw new InvalidOperationException(string.Format(UnresolvedDependencyError, dependency)); - } - } - - return emitter; - } - - private void EmitDependencyUsingFactoryExpression(IEmitter emitter, Dependency dependency) - { - var parameterExpression = (ParameterExpression)dependency.FactoryExpression.AsEnumerable().FirstOrDefault(e => e is ParameterExpression && e.Type == typeof(IServiceFactory)); - - if (parameterExpression != null) - { - var lambda = Expression.Lambda(dependency.FactoryExpression, new[] { parameterExpression }).Compile(); - MethodInfo methodInfo = lambda.GetType().GetMethod("Invoke"); - emitter.PushConstant(constants.Add(lambda), lambda.GetType()); - emitter.PushConstant(constants.Add(this), typeof(IServiceFactory)); - emitter.Call(methodInfo); - } - else - { - var lambda = Expression.Lambda(dependency.FactoryExpression, new ParameterExpression[] { }).Compile(); - MethodInfo methodInfo = lambda.GetType().GetMethod("Invoke"); - emitter.PushConstant(constants.Add(lambda), lambda.GetType()); - emitter.Call(methodInfo); - } - } - - private void EmitPropertyDependencies(ConstructionInfo constructionInfo, IEmitter emitter) - { - if (constructionInfo.PropertyDependencies.Count == 0) - { - return; - } - - LocalBuilder instanceVariable = emitter.DeclareLocal(constructionInfo.ImplementingType); - emitter.Store(instanceVariable); - foreach (var propertyDependency in constructionInfo.PropertyDependencies) - { - EmitPropertyDependency(emitter, propertyDependency, instanceVariable); - } - - emitter.Push(instanceVariable); - } - - private Action CreateEmitMethodForUnknownService(Type serviceType, string serviceName) - { - Action emitter = null; - if (serviceType.IsLazy()) - { - emitter = CreateEmitMethodBasedOnLazyServiceRequest(serviceType, t => t.CreateGetInstanceDelegate(this)); - } - else if (serviceType.IsFuncWithParameters()) - { - emitter = CreateEmitMethodBasedParameterizedFuncRequest(serviceType, serviceName); - } - else if (serviceType.IsFunc()) - { - emitter = CreateEmitMethodBasedOnFuncServiceRequest(serviceType, serviceName); - } - else if (serviceType.IsEnumerableOfT()) - { - emitter = CreateEmitMethodForEnumerableServiceServiceRequest(serviceType); - } - else if (serviceType.IsArray) - { - emitter = CreateEmitMethodForArrayServiceRequest(serviceType); - } - else if (serviceType.IsReadOnlyCollectionOfT() || serviceType.IsReadOnlyListOfT()) - { - emitter = CreateEmitMethodForReadOnlyCollectionServiceRequest(serviceType); - } - else if (serviceType.IsListOfT()) - { - emitter = CreateEmitMethodForListServiceRequest(serviceType); - } - else if (serviceType.IsCollectionOfT()) - { - emitter = CreateEmitMethodForListServiceRequest(serviceType); - } - else if (CanRedirectRequestForDefaultServiceToSingleNamedService(serviceType, serviceName)) - { - emitter = CreateServiceEmitterBasedOnSingleNamedInstance(serviceType); - } - else if (serviceType.IsClosedGeneric()) - { - emitter = CreateEmitMethodBasedOnClosedGenericServiceRequest(serviceType, serviceName); - } - - UpdateEmitMethod(serviceType, serviceName, emitter); - - return emitter; - } - - private Action CreateEmitMethodBasedOnFuncServiceRequest(Type serviceType, string serviceName) - { - Delegate getInstanceDelegate; - var returnType = serviceType.GetGenericTypeArguments().Single(); - if (string.IsNullOrEmpty(serviceName)) - { - getInstanceDelegate = returnType.CreateGetInstanceDelegate(this); - } - else - { - getInstanceDelegate = returnType.CreateNamedGetInstanceDelegate(serviceName, this); - } - - var constantIndex = constants.Add(getInstanceDelegate); - return e => e.PushConstant(constantIndex, serviceType); - } - - private Action CreateEmitMethodBasedParameterizedFuncRequest(Type serviceType, string serviceName) - { - Delegate getInstanceDelegate; - if (string.IsNullOrEmpty(serviceName)) - { - getInstanceDelegate = CreateGetInstanceWithParametersDelegate(serviceType); - } - else - { - getInstanceDelegate = ReflectionHelper.CreateGetNamedInstanceWithParametersDelegate( - this, - serviceType, - serviceName); - } - - var constantIndex = constants.Add(getInstanceDelegate); - return e => e.PushConstant(constantIndex, serviceType); - } - - private Delegate CreateGetInstanceWithParametersDelegate(Type serviceType) - { - var getInstanceMethod = ReflectionHelper.GetGetInstanceWithParametersMethod(serviceType); - return getInstanceMethod.CreateDelegate(serviceType, this); - } - - private Action CreateServiceEmitterBasedOnFactoryRule(FactoryRule rule, Type serviceType, string serviceName) - { - var serviceRegistration = new ServiceRegistration { ServiceType = serviceType, ServiceName = serviceName, Lifetime = CloneLifeTime(rule.LifeTime) }; - ParameterExpression serviceFactoryParameterExpression = Expression.Parameter(typeof(IServiceFactory)); - ConstantExpression serviceRequestConstantExpression = Expression.Constant(new ServiceRequest(serviceType, serviceName, this)); - ConstantExpression delegateConstantExpression = Expression.Constant(rule.Factory); - Type delegateType = typeof(Func<,>).MakeGenericType(typeof(IServiceFactory), serviceType); - UnaryExpression convertExpression = Expression.Convert( - Expression.Invoke(delegateConstantExpression, serviceRequestConstantExpression), serviceType); - - LambdaExpression lambdaExpression = Expression.Lambda(delegateType, convertExpression, serviceFactoryParameterExpression); - serviceRegistration.FactoryExpression = lambdaExpression; - - if (rule.LifeTime != null) - { - return methodSkeleton => EmitLifetime(serviceRegistration, ms => EmitNewInstanceWithDecorators(serviceRegistration, ms), methodSkeleton); - } - - return methodSkeleton => EmitNewInstanceWithDecorators(serviceRegistration, methodSkeleton); - } - - private Action CreateEmitMethodForArrayServiceRequest(Type serviceType) - { - Action enumerableEmitter = CreateEmitMethodForEnumerableServiceServiceRequest(serviceType); - return enumerableEmitter; - } - - private Action CreateEmitMethodForListServiceRequest(Type serviceType) - { - // Note replace this with getEmitMethod(); - Action enumerableEmitter = CreateEmitMethodForEnumerableServiceServiceRequest(serviceType); - - MethodInfo openGenericToArrayMethod = typeof(Enumerable).GetMethod("ToList"); - MethodInfo closedGenericToListMethod = openGenericToArrayMethod.MakeGenericMethod(TypeHelper.GetElementType(serviceType)); - return ms => - { - enumerableEmitter(ms); - ms.Emit(OpCodes.Call, closedGenericToListMethod); - }; - } - - private Action CreateEmitMethodForReadOnlyCollectionServiceRequest(Type serviceType) - { - Type elementType = TypeHelper.GetElementType(serviceType); - Type closedGenericReadOnlyCollectionType = typeof(ReadOnlyCollection<>).MakeGenericType(elementType); - ConstructorInfo constructorInfo = closedGenericReadOnlyCollectionType.GetConstructors()[0]; - - Action listEmitMethod = CreateEmitMethodForListServiceRequest(serviceType); - - return emitter => - { - listEmitMethod(emitter); - emitter.New(constructorInfo); - }; - } - - private void EnsureEmitMethodsForOpenGenericTypesAreCreated(Type actualServiceType) - { - var openGenericServiceType = actualServiceType.GetGenericTypeDefinition(); - var openGenericServiceEmitters = GetAvailableServices(openGenericServiceType); - foreach (var openGenericEmitterEntry in openGenericServiceEmitters.Keys) - { - GetRegisteredEmitMethod(actualServiceType, openGenericEmitterEntry); - } - } - - private Action CreateEmitMethodBasedOnLazyServiceRequest(Type serviceType, Func valueFactoryDelegate) - { - Type actualServiceType = serviceType.GetGenericTypeArguments()[0]; - Type funcType = actualServiceType.GetFuncType(); - ConstructorInfo lazyConstructor = actualServiceType.GetLazyConstructor(); - Delegate getInstanceDelegate = valueFactoryDelegate(actualServiceType); - var constantIndex = constants.Add(getInstanceDelegate); - - return emitter => - { - emitter.PushConstant(constantIndex, funcType); - emitter.New(lazyConstructor); - }; - } - - private ServiceRegistration GetOpenGenericServiceRegistration(Type openGenericServiceType, string serviceName) - { - var services = GetAvailableServices(openGenericServiceType); - if (services.Count == 0) - { - return null; - } - - ServiceRegistration openGenericServiceRegistration; - services.TryGetValue(serviceName, out openGenericServiceRegistration); - if (openGenericServiceRegistration == null && string.IsNullOrEmpty(serviceName) && services.Count == 1) - { - return services.First().Value; - } - - return openGenericServiceRegistration; - } - - private Action CreateEmitMethodBasedOnClosedGenericServiceRequest(Type closedGenericServiceType, string serviceName) - { - Type openGenericServiceType = closedGenericServiceType.GetGenericTypeDefinition(); - ServiceRegistration openGenericServiceRegistration = - GetOpenGenericServiceRegistration(openGenericServiceType, serviceName); - - if (openGenericServiceRegistration == null) - { - return null; - } - - Type[] closedGenericArguments = closedGenericServiceType.GetGenericTypeArguments(); - - Type closedGenericImplementingType = TryMakeGenericType( - openGenericServiceRegistration.ImplementingType, - closedGenericArguments); - - if (closedGenericImplementingType == null) - { - return null; - } - - var serviceRegistration = new ServiceRegistration - { - ServiceType = closedGenericServiceType, - ImplementingType = - closedGenericImplementingType, - ServiceName = serviceName, - Lifetime = - CloneLifeTime( - openGenericServiceRegistration - .Lifetime) - }; - Register(serviceRegistration); - return GetEmitMethod(serviceRegistration.ServiceType, serviceRegistration.ServiceName); - } - - private Action CreateEmitMethodForEnumerableServiceServiceRequest(Type serviceType) - { - Type actualServiceType = TypeHelper.GetElementType(serviceType); - if (actualServiceType.IsGenericType()) - { - EnsureEmitMethodsForOpenGenericTypesAreCreated(actualServiceType); - } - - var emitMethods = emitters.Where(kv => actualServiceType.IsAssignableFrom(kv.Key)).SelectMany(kv => kv.Value.Values).ToList(); - - if (dependencyStack.Count > 0 && emitMethods.Contains(dependencyStack.Peek())) - { - emitMethods.Remove(dependencyStack.Peek()); - } - - return e => EmitEnumerable(emitMethods, actualServiceType, e); - } - - private Action CreateServiceEmitterBasedOnSingleNamedInstance(Type serviceType) - { - return GetEmitMethod(serviceType, GetEmitMethods(serviceType).First().Key); - } - - private bool CanRedirectRequestForDefaultServiceToSingleNamedService(Type serviceType, string serviceName) - { - return string.IsNullOrEmpty(serviceName) && GetEmitMethods(serviceType).Count == 1; - } - - private ConstructionInfo GetConstructionInfo(Registration registration) - { - return constructionInfoProvider.Value.GetConstructionInfo(registration); - } - - private ThreadSafeDictionary> GetEmitMethods(Type serviceType) - { - return emitters.GetOrAdd(serviceType, s => new ThreadSafeDictionary>(StringComparer.CurrentCultureIgnoreCase)); - } - - private ThreadSafeDictionary GetAvailableServices(Type serviceType) - { - return availableServices.GetOrAdd(serviceType, s => new ThreadSafeDictionary(StringComparer.CurrentCultureIgnoreCase)); - } - - private void RegisterService(Type serviceType, Type implementingType, ILifetime lifetime, string serviceName) - { - var serviceRegistration = new ServiceRegistration { ServiceType = serviceType, ImplementingType = implementingType, ServiceName = serviceName, Lifetime = lifetime }; - Register(serviceRegistration); - } - - private Action ResolveEmitMethod(ServiceRegistration serviceRegistration) - { - if (serviceRegistration.Lifetime == null) - { - return methodSkeleton => EmitNewInstanceWithDecorators(serviceRegistration, methodSkeleton); - } - - return methodSkeleton => EmitLifetime(serviceRegistration, ms => EmitNewInstanceWithDecorators(serviceRegistration, ms), methodSkeleton); - } - - private void EmitLifetime(ServiceRegistration serviceRegistration, Action emitMethod, IEmitter emitter) - { - if (serviceRegistration.Lifetime is PerContainerLifetime) - { - Func instanceDelegate = - WrapAsFuncDelegate(CreateDynamicMethodDelegate(emitMethod)); - var instance = serviceRegistration.Lifetime.GetInstance(instanceDelegate, null); - var instanceIndex = constants.Add(instance); - emitter.PushConstant(instanceIndex, instance.GetType()); - } - else - { - int instanceDelegateIndex = CreateInstanceDelegateIndex(emitMethod); - int lifetimeIndex = CreateLifetimeIndex(serviceRegistration.Lifetime); - int scopeManagerProviderIndex = CreateScopeManagerProviderIndex(); - var getInstanceMethod = LifetimeHelper.GetInstanceMethod; - emitter.PushConstant(lifetimeIndex, typeof(ILifetime)); - emitter.PushConstant(instanceDelegateIndex, typeof(Func)); - emitter.PushConstant(scopeManagerProviderIndex, typeof(IScopeManagerProvider)); - emitter.Call(LifetimeHelper.GetScopeManagerMethod); - emitter.Call(LifetimeHelper.GetCurrentScopeMethod); - emitter.Call(getInstanceMethod); - } - } - - private int CreateScopeManagerProviderIndex() - { - return constants.Add(ScopeManagerProvider); - } - - private int CreateInstanceDelegateIndex(Action emitMethod) - { - return constants.Add(WrapAsFuncDelegate(CreateDynamicMethodDelegate(emitMethod))); - } - - private int CreateLifetimeIndex(ILifetime lifetime) - { - return constants.Add(lifetime); - } - - private Func CreateDefaultDelegate(Type serviceType, bool throwError) - { - var instanceDelegate = CreateDelegate(serviceType, string.Empty, throwError); - if (instanceDelegate == null) - { - return c => null; - } - - Interlocked.Exchange(ref delegates, delegates.Add(serviceType, instanceDelegate)); - return instanceDelegate; - } - - private Func CreateNamedDelegate(Tuple key, bool throwError) - { - var instanceDelegate = CreateDelegate(key.Item1, key.Item2, throwError); - if (instanceDelegate == null) - { - return c => null; - } - - Interlocked.Exchange(ref namedDelegates, namedDelegates.Add(key, instanceDelegate)); - return instanceDelegate; - } - - private Func CreateDelegate(Type serviceType, string serviceName, bool throwError) - { - lock (lockObject) - { - var serviceEmitter = GetEmitMethod(serviceType, serviceName); - if (serviceEmitter == null && throwError) - { - throw new InvalidOperationException( - string.Format("Unable to resolve type: {0}, service name: {1}", serviceType, serviceName)); - } - - if (serviceEmitter != null) - { - try - { - return CreateDynamicMethodDelegate(serviceEmitter); - } - catch (InvalidOperationException ex) - { - dependencyStack.Clear(); - throw new InvalidOperationException( - string.Format("Unable to resolve type: {0}, service name: {1}", serviceType, serviceName), - ex); - } - } - - return null; - } - } - - private void RegisterValue(Type serviceType, object value, string serviceName) - { - var serviceRegistration = new ServiceRegistration { ServiceType = serviceType, ServiceName = serviceName, Value = value, Lifetime = new PerContainerLifetime() }; - Register(serviceRegistration); - } - - private void RegisterServiceFromLambdaExpression( - LambdaExpression factory, ILifetime lifetime, string serviceName) - { - var serviceRegistration = new ServiceRegistration { ServiceType = typeof(TService), FactoryExpression = factory, ServiceName = serviceName, Lifetime = lifetime }; - Register(serviceRegistration); - } - - private class Storage - { - public T[] Items = new T[0]; - - private readonly object lockObject = new object(); - - public int Add(T value) - { - int index = Array.IndexOf(Items, value); - if (index == -1) - { - return TryAddValue(value); - } - - return index; - } - - public void Clear() - { - lock (lockObject) - { - Items = new T[0]; - } - } - - private int TryAddValue(T value) - { - lock (lockObject) - { - int index = Array.IndexOf(Items, value); - if (index == -1) - { - index = AddValue(value); - } - - return index; - } - } - - private int AddValue(T value) - { - int index = Items.Length; - T[] snapshot = CreateSnapshot(); - snapshot[index] = value; - Items = snapshot; - return index; - } - - private T[] CreateSnapshot() - { - var snapshot = new T[Items.Length + 1]; - Array.Copy(Items, snapshot, Items.Length); - return snapshot; - } - } - - private class DynamicMethodSkeleton : IMethodSkeleton - { - private IEmitter emitter; - private DynamicMethod dynamicMethod; - - public DynamicMethodSkeleton(Type returnType, Type[] parameterTypes) - { - CreateDynamicMethod(returnType, parameterTypes); - } - - public IEmitter GetEmitter() - { - return emitter; - } - - public Delegate CreateDelegate(Type delegateType) - { - return dynamicMethod.CreateDelegate(delegateType); - } - - private void CreateDynamicMethod(Type returnType, Type[] parameterTypes) - { - dynamicMethod = new DynamicMethod( - "DynamicMethod", returnType, parameterTypes, typeof(ServiceContainer).Module, true); - emitter = new Emitter(dynamicMethod.GetILGenerator(), parameterTypes); - } - } - - private class ServiceRegistry : ThreadSafeDictionary> - { - } - - private class FactoryRule - { - public Func CanCreateInstance { get; set; } - - public Func Factory { get; set; } - - public ILifetime LifeTime { get; set; } - } - - private class ServiceOverride - { - public Func CanOverride { get; set; } - - public Func ServiceRegistrationFactory { get; set; } - } - } - - /// - /// A that provides a per thread. - /// - [System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage] - internal class PerThreadScopeManagerProvider : IScopeManagerProvider - { - private readonly ThreadLocal scopeManagers = - new ThreadLocal(() => new ScopeManager()); - - /// - /// Returns the that is responsible for managing scopes. - /// - /// The that is responsible for managing scopes. - public ScopeManager GetScopeManager() - { - return scopeManagers.Value; - } - } - - /// - /// A that provides a per - /// . - /// - [System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage] - internal class PerLogicalCallContextScopeManagerProvider : IScopeManagerProvider - { - private readonly LogicalThreadStorage scopeManagers = - new LogicalThreadStorage(() => new ScopeManager()); - - /// - /// Returns the that is responsible for managing scopes. - /// - /// The that is responsible for managing scopes. - public ScopeManager GetScopeManager() - { - return scopeManagers.Value; - } - } - - /// - /// A thread safe dictionary. - /// - /// The type of the keys in the dictionary. - /// The type of the values in the dictionary. - [System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage] - internal class ThreadSafeDictionary : ConcurrentDictionary - { - /// - /// Initializes a new instance of the class. - /// - public ThreadSafeDictionary() - { - } - - /// - /// Initializes a new instance of the class using the - /// given . - /// - /// The implementation to use when comparing keys - public ThreadSafeDictionary(IEqualityComparer comparer) - : base(comparer) - { - } - } - - /// - /// Selects the from a given type that represents the most resolvable constructor. - /// - [System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage] - internal class MostResolvableConstructorSelector : IConstructorSelector - { - private readonly Func canGetInstance; - - /// - /// Initializes a new instance of the class. - /// - /// A function delegate that determines if a service type can be resolved. - public MostResolvableConstructorSelector(Func canGetInstance) - { - this.canGetInstance = canGetInstance; - } - - /// - /// Selects the constructor to be used when creating a new instance of the . - /// - /// The for which to return a . - /// A instance that represents the constructor to be used - /// when creating a new instance of the . - public ConstructorInfo Execute(Type implementingType) - { - ConstructorInfo[] constructorCandidates = implementingType.GetConstructors(); - if (constructorCandidates.Length == 0) - { - throw new InvalidOperationException("Missing public constructor for Type: " + implementingType.FullName); - } - - if (constructorCandidates.Length == 1) - { - return constructorCandidates[0]; - } - - foreach (var constructorCandidate in constructorCandidates.OrderByDescending(c => c.GetParameters().Count())) - { - ParameterInfo[] parameters = constructorCandidate.GetParameters(); - if (CanCreateParameterDependencies(parameters)) - { - return constructorCandidate; - } - } - - throw new InvalidOperationException("No resolvable constructor found for Type: " + implementingType.FullName); - } - - /// - /// Gets the service name based on the given . - /// - /// The for which to get the service name. - /// The name of the service for the given . - protected virtual string GetServiceName(ParameterInfo parameter) - { - return parameter.Name; - } - - private bool CanCreateParameterDependencies(IEnumerable parameters) - { - return parameters.All(CanCreateParameterDependency); - } - - private bool CanCreateParameterDependency(ParameterInfo parameterInfo) - { - return canGetInstance(parameterInfo.ParameterType, string.Empty) || canGetInstance(parameterInfo.ParameterType, GetServiceName(parameterInfo)); - } - } - - /// - /// Selects the constructor dependencies for a given . - /// - [System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage] - internal class ConstructorDependencySelector : IConstructorDependencySelector - { - /// - /// Selects the constructor dependencies for the given . - /// - /// The for which to select the constructor dependencies. - /// A list of instances that represents the constructor - /// dependencies for the given . - public virtual IEnumerable Execute(ConstructorInfo constructor) - { - return - constructor.GetParameters() - .OrderBy(p => p.Position) - .Select( - p => - new ConstructorDependency - { - ServiceName = string.Empty, - ServiceType = p.ParameterType, - Parameter = p, - IsRequired = true - }); - } - } - - /// - /// Selects the property dependencies for a given . - /// - [System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage] - internal class PropertyDependencySelector : IPropertyDependencySelector - { - /// - /// Initializes a new instance of the class. - /// - /// The that is - /// responsible for selecting a list of injectable properties. - public PropertyDependencySelector(IPropertySelector propertySelector) - { - PropertySelector = propertySelector; - } - - /// - /// Gets the that is responsible for selecting a - /// list of injectable properties. - /// - protected IPropertySelector PropertySelector { get; private set; } - - /// - /// Selects the property dependencies for the given . - /// - /// The for which to select the property dependencies. - /// A list of instances that represents the property - /// dependencies for the given . - public virtual IEnumerable Execute(Type type) - { - return PropertySelector.Execute(type).Select( - p => new PropertyDependency { Property = p, ServiceName = string.Empty, ServiceType = p.PropertyType }); - } - } - - /// - /// Builds a instance based on the implementing . - /// - [System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage] - internal class TypeConstructionInfoBuilder : ITypeConstructionInfoBuilder - { - private readonly IConstructorSelector constructorSelector; - private readonly IConstructorDependencySelector constructorDependencySelector; - private readonly IPropertyDependencySelector propertyDependencySelector; - - /// - /// Initializes a new instance of the class. - /// - /// The that is responsible - /// for selecting the constructor to be used for constructor injection. - /// The that is - /// responsible for selecting the constructor dependencies for a given . - /// The that is responsible - /// for selecting the property dependencies for a given . - public TypeConstructionInfoBuilder( - IConstructorSelector constructorSelector, - IConstructorDependencySelector constructorDependencySelector, - IPropertyDependencySelector propertyDependencySelector) - { - this.constructorSelector = constructorSelector; - this.constructorDependencySelector = constructorDependencySelector; - this.propertyDependencySelector = propertyDependencySelector; - } - - /// - /// Analyzes the and returns a instance. - /// - /// The that represents the implementing type to analyze. - /// A instance. - public ConstructionInfo Execute(Registration registration) - { - var implementingType = registration.ImplementingType; - var constructionInfo = new ConstructionInfo(); - constructionInfo.ImplementingType = implementingType; - constructionInfo.PropertyDependencies.AddRange(propertyDependencySelector.Execute(implementingType)); - if (!registration.IgnoreConstructorDependencies) - { - constructionInfo.Constructor = constructorSelector.Execute(implementingType); - constructionInfo.ConstructorDependencies.AddRange(constructorDependencySelector.Execute(constructionInfo.Constructor)); - } - - return constructionInfo; - } - } - - /// - /// Keeps track of a instance for each . - /// - [System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage] - internal class ConstructionInfoProvider : IConstructionInfoProvider - { - private readonly IConstructionInfoBuilder constructionInfoBuilder; - private readonly ThreadSafeDictionary cache = new ThreadSafeDictionary(); - - /// - /// Initializes a new instance of the class. - /// - /// The that - /// is responsible for building a instance based on a given . - public ConstructionInfoProvider(IConstructionInfoBuilder constructionInfoBuilder) - { - this.constructionInfoBuilder = constructionInfoBuilder; - } - - /// - /// Gets a instance for the given . - /// - /// The for which to get a instance. - /// The instance that describes how to create an instance of the given . - public ConstructionInfo GetConstructionInfo(Registration registration) - { - return cache.GetOrAdd(registration, constructionInfoBuilder.Execute); - } - - /// - /// Invalidates the and causes new instances - /// to be created when the method is called. - /// - public void Invalidate() - { - cache.Clear(); - } - } - - /// - /// Provides a instance - /// that describes how to create a service instance. - /// - [System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage] - internal class ConstructionInfoBuilder : IConstructionInfoBuilder - { - private readonly Lazy lambdaConstructionInfoBuilder; - private readonly Lazy typeConstructionInfoBuilder; - - /// - /// Initializes a new instance of the class. - /// - /// - /// A function delegate used to provide a instance. - /// - /// - /// A function delegate used to provide a instance. - /// - public ConstructionInfoBuilder( - Func lambdaConstructionInfoBuilderFactory, - Func typeConstructionInfoBuilderFactory) - { - typeConstructionInfoBuilder = new Lazy(typeConstructionInfoBuilderFactory); - lambdaConstructionInfoBuilder = new Lazy(lambdaConstructionInfoBuilderFactory); - } - - /// - /// Returns a instance based on the given . - /// - /// The for which to return a instance. - /// A instance that describes how to create a service instance. - public ConstructionInfo Execute(Registration registration) - { - return registration.FactoryExpression != null - ? CreateConstructionInfoFromLambdaExpression(registration.FactoryExpression) - : CreateConstructionInfoFromImplementingType(registration); - } - - private ConstructionInfo CreateConstructionInfoFromLambdaExpression(LambdaExpression lambdaExpression) - { - return lambdaConstructionInfoBuilder.Value.Execute(lambdaExpression); - } - - private ConstructionInfo CreateConstructionInfoFromImplementingType(Registration registration) - { - return typeConstructionInfoBuilder.Value.Execute(registration); - } - } - - /// - /// Parses a into a instance. - /// - [System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage] - internal class LambdaConstructionInfoBuilder : ILambdaConstructionInfoBuilder - { - /// - /// Parses the and returns a instance. - /// - /// The to parse. - /// A instance. - public ConstructionInfo Execute(LambdaExpression lambdaExpression) - { - if (!CanParse(lambdaExpression)) - { - return CreateConstructionInfoBasedOnLambdaExpression(lambdaExpression); - } - - switch (lambdaExpression.Body.NodeType) - { - case ExpressionType.New: - return CreateConstructionInfoBasedOnNewExpression((NewExpression)lambdaExpression.Body); - case ExpressionType.MemberInit: - return CreateConstructionInfoBasedOnHandleMemberInitExpression((MemberInitExpression)lambdaExpression.Body); - default: - return CreateConstructionInfoBasedOnLambdaExpression(lambdaExpression); - } - } - - private bool CanParse(LambdaExpression lambdaExpression) - { - return lambdaExpression.Parameters.Count <= 1; - } - - private static ConstructionInfo CreateConstructionInfoBasedOnLambdaExpression(LambdaExpression lambdaExpression) - { - return new ConstructionInfo { FactoryDelegate = lambdaExpression.Compile() }; - } - - private static ConstructionInfo CreateConstructionInfoBasedOnNewExpression(NewExpression newExpression) - { - var constructionInfo = CreateConstructionInfo(newExpression); - ParameterInfo[] parameters = newExpression.Constructor.GetParameters(); - for (int i = 0; i < parameters.Length; i++) - { - ConstructorDependency constructorDependency = CreateConstructorDependency(parameters[i]); - ApplyDependencyDetails(newExpression.Arguments[i], constructorDependency); - constructionInfo.ConstructorDependencies.Add(constructorDependency); - } - - return constructionInfo; - } - - private static ConstructionInfo CreateConstructionInfo(NewExpression newExpression) - { - var constructionInfo = new ConstructionInfo { Constructor = newExpression.Constructor, ImplementingType = newExpression.Constructor.DeclaringType }; - return constructionInfo; - } - - private static ConstructionInfo CreateConstructionInfoBasedOnHandleMemberInitExpression(MemberInitExpression memberInitExpression) - { - var constructionInfo = CreateConstructionInfoBasedOnNewExpression(memberInitExpression.NewExpression); - foreach (MemberBinding memberBinding in memberInitExpression.Bindings) - { - HandleMemberAssignment((MemberAssignment)memberBinding, constructionInfo); - } - - return constructionInfo; - } - - private static void HandleMemberAssignment(MemberAssignment memberAssignment, ConstructionInfo constructionInfo) - { - var propertyDependency = CreatePropertyDependency(memberAssignment); - ApplyDependencyDetails(memberAssignment.Expression, propertyDependency); - constructionInfo.PropertyDependencies.Add(propertyDependency); - } - - private static ConstructorDependency CreateConstructorDependency(ParameterInfo parameterInfo) - { - var constructorDependency = new ConstructorDependency - { - Parameter = parameterInfo, - ServiceType = parameterInfo.ParameterType, - IsRequired = true - }; - return constructorDependency; - } - - private static PropertyDependency CreatePropertyDependency(MemberAssignment memberAssignment) - { - var propertyDependecy = new PropertyDependency - { - Property = (PropertyInfo)memberAssignment.Member, - ServiceType = ((PropertyInfo)memberAssignment.Member).PropertyType - }; - return propertyDependecy; - } - - private static void ApplyDependencyDetails(Expression expression, Dependency dependency) - { - if (RepresentsServiceFactoryMethod(expression)) - { - ApplyDependencyDetailsFromMethodCall((MethodCallExpression)expression, dependency); - } - else - { - ApplyDependecyDetailsFromExpression(expression, dependency); - } - } - - private static bool RepresentsServiceFactoryMethod(Expression expression) - { - return IsMethodCall(expression) && - IsServiceFactoryMethod(((MethodCallExpression)expression).Method); - } - - private static bool IsMethodCall(Expression expression) - { - return expression.NodeType == ExpressionType.Call; - } - - private static bool IsServiceFactoryMethod(MethodInfo methodInfo) - { - return methodInfo.DeclaringType == typeof(IServiceFactory); - } - - private static void ApplyDependecyDetailsFromExpression(Expression expression, Dependency dependency) - { - dependency.FactoryExpression = expression; - dependency.ServiceName = string.Empty; - } - - private static void ApplyDependencyDetailsFromMethodCall(MethodCallExpression methodCallExpression, Dependency dependency) - { - dependency.ServiceType = methodCallExpression.Method.ReturnType; - if (RepresentsGetNamedInstanceMethod(methodCallExpression)) - { - dependency.ServiceName = (string)((ConstantExpression)methodCallExpression.Arguments[0]).Value; - } - else - { - dependency.ServiceName = string.Empty; - } - } - - private static bool RepresentsGetNamedInstanceMethod(MethodCallExpression node) - { - return IsGetInstanceMethod(node.Method) && HasOneArgumentRepresentingServiceName(node); - } - - private static bool IsGetInstanceMethod(MethodInfo methodInfo) - { - return methodInfo.Name == "GetInstance"; - } - - private static bool HasOneArgumentRepresentingServiceName(MethodCallExpression node) - { - return HasOneArgument(node) && IsConstantExpression(node.Arguments[0]); - } - - private static bool HasOneArgument(MethodCallExpression node) - { - return node.Arguments.Count == 1; - } - - private static bool IsConstantExpression(Expression argument) - { - return argument.NodeType == ExpressionType.Constant; - } - } - - /// - /// Contains information about a service request that originates from a rule based service registration. - /// - [System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage] - internal class ServiceRequest - { - /// - /// Initializes a new instance of the class. - /// - /// The of the requested service. - /// The name of the requested service. - /// The to be associated with this . - public ServiceRequest(Type serviceType, string serviceName, IServiceFactory serviceFactory) - { - ServiceType = serviceType; - ServiceName = serviceName; - ServiceFactory = serviceFactory; - } - - /// - /// Gets the service type. - /// - public Type ServiceType { get; private set; } - - /// - /// Gets the service name. - /// - public string ServiceName { get; private set; } - - /// - /// Gets the that is associated with this . - /// - public IServiceFactory ServiceFactory { get; private set; } - } - - /// - /// Base class for concrete registrations within the service container. - /// - internal abstract class Registration - { - /// - /// Gets or sets the service . - /// - public Type ServiceType { get; set; } - - /// - /// Gets or sets a value indicating whether constructor dependencies should be ignored. - /// - public bool IgnoreConstructorDependencies { get; set; } - - /// - /// Gets or sets the that implements the . - /// - public virtual Type ImplementingType { get; set; } - - /// - /// Gets or sets the used to create a service instance. - /// - public LambdaExpression FactoryExpression { get; set; } - } - - /// - /// Contains information about a registered decorator. - /// - [System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage] - internal class DecoratorRegistration : Registration - { - /// - /// Gets or sets a function delegate that determines if the decorator can decorate the service - /// represented by the supplied . - /// - public Func CanDecorate { get; set; } - - /// - /// Gets or sets a that defers resolving of the decorators implementing type. - /// - public Func ImplementingTypeFactory { get; set; } - - /// - /// Gets or sets the index of this . - /// - public int Index { get; set; } - - /// - /// Gets a value indicating whether this registration has a deferred implementing type. - /// - public bool HasDeferredImplementingType - { - get - { - return ImplementingType == null && FactoryExpression == null; - } - } - } - - /// - /// Contains information about a registered service. - /// - [System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage] - internal class ServiceRegistration : Registration - { - /// - /// Gets or sets the name of the service. - /// - public string ServiceName { get; set; } - - /// - /// Gets or sets the instance that controls the lifetime of the service. - /// - public ILifetime Lifetime { get; set; } - - /// - /// Gets or sets the value that represents the instance of the service. - /// - public object Value { get; set; } - - /// - /// Gets or sets a value indicating whether this can be overridden - /// by another registration. - /// - public bool IsReadOnly { get; set; } - - /// - /// Serves as a hash function for a particular type. - /// - /// - /// A hash code for the current . - /// - /// 2 - public override int GetHashCode() - { - return ServiceType.GetHashCode() ^ ServiceName.GetHashCode(); - } - - /// - /// Determines whether the specified is equal to the current . - /// - /// - /// True if the specified is equal to the current ; otherwise, false. - /// - /// The to compare with the current . 2 - public override bool Equals(object obj) - { - var other = obj as ServiceRegistration; - if (other == null) - { - return false; - } - - var result = ServiceName == other.ServiceName && ServiceType == other.ServiceType; - return result; - } - } - - /// - /// Contains information about how to create a service instance. - /// - [System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage] - internal class ConstructionInfo - { - /// - /// Initializes a new instance of the class. - /// - public ConstructionInfo() - { - PropertyDependencies = new List(); - ConstructorDependencies = new List(); - } - - /// - /// Gets or sets the implementing type that represents the concrete class to create. - /// - public Type ImplementingType { get; set; } - - /// - /// Gets or sets the that is used to create a service instance. - /// - public ConstructorInfo Constructor { get; set; } - - /// - /// Gets a list of instances that represent - /// the property dependencies for the target service instance. - /// - public List PropertyDependencies { get; private set; } - - /// - /// Gets a list of instances that represent - /// the property dependencies for the target service instance. - /// - public List ConstructorDependencies { get; private set; } - - /// - /// Gets or sets the function delegate to be used to create the service instance. - /// - public Delegate FactoryDelegate { get; set; } - } - - /// - /// Represents a class dependency. - /// - internal abstract class Dependency - { - /// - /// Gets or sets the service of the . - /// - public Type ServiceType { get; set; } - - /// - /// Gets or sets the service name of the . - /// - public string ServiceName { get; set; } - - /// - /// Gets or sets the that represent getting the value of the . - /// - public Expression FactoryExpression { get; set; } - - /// - /// Gets the name of the dependency accessor. - /// - public abstract string Name { get; } - - /// - /// Gets or sets a value indicating whether this dependency is required. - /// - public bool IsRequired { get; set; } - - /// - /// Returns textual information about the dependency. - /// - /// A string that describes the dependency. - public override string ToString() - { - var sb = new StringBuilder(); - return sb.AppendFormat("[Requested dependency: ServiceType:{0}, ServiceName:{1}]", ServiceType, ServiceName).ToString(); - } - } - - /// - /// Represents a property dependency. - /// - [System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage] - internal class PropertyDependency : Dependency - { - /// - /// Gets or sets the that is used to set the property value. - /// - public PropertyInfo Property { get; set; } - - /// - /// Gets the name of the dependency accessor. - /// - public override string Name - { - get - { - return Property.Name; - } - } - - /// - /// Returns textual information about the dependency. - /// - /// A string that describes the dependency. - public override string ToString() - { - return string.Format("[Target Type: {0}], [Property: {1}({2})]", Property.DeclaringType, Property.Name, Property.PropertyType) + ", " + base.ToString(); - } - } - - /// - /// Represents a constructor dependency. - /// - [System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage] - internal class ConstructorDependency : Dependency - { - /// - /// Gets or sets the for this . - /// - public ParameterInfo Parameter { get; set; } - - /// - /// Gets or sets a value indicating whether that this parameter represents - /// the decoration target passed into a decorator instance. - /// - public bool IsDecoratorTarget { get; set; } - - /// - /// Gets the name of the dependency accessor. - /// - public override string Name - { - get - { - return Parameter.Name; - } - } - - /// - /// Returns textual information about the dependency. - /// - /// A string that describes the dependency. - public override string ToString() - { - return string.Format("[Target Type: {0}], [Parameter: {1}({2})]", Parameter.Member.DeclaringType, Parameter.Name, Parameter.ParameterType) + ", " + base.ToString(); - } - } - - /// - /// Ensures that only one instance of a given service can exist within the current . - /// - [System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage] - internal class PerContainerLifetime : ILifetime, IDisposable - { - private readonly object syncRoot = new object(); - private volatile object singleton; - - /// - /// Returns a service instance according to the specific lifetime characteristics. - /// - /// The function delegate used to create a new service instance. - /// The of the current service request. - /// The requested services instance. - public object GetInstance(Func createInstance, Scope scope) - { - if (singleton != null) - { - return singleton; - } - - lock (syncRoot) - { - if (singleton == null) - { - singleton = createInstance(); - } - } - - return singleton; - } - - /// - /// Disposes the service instances managed by this instance. - /// - public void Dispose() - { - var disposable = singleton as IDisposable; - if (disposable != null) - { - disposable.Dispose(); - } - } - } - - /// - /// Ensures that a new instance is created for each request in addition to tracking disposable instances. - /// - [System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage] - internal class PerRequestLifeTime : ILifetime - { - /// - /// Returns a service instance according to the specific lifetime characteristics. - /// - /// The function delegate used to create a new service instance. - /// The of the current service request. - /// The requested services instance. - public object GetInstance(Func createInstance, Scope scope) - { - var instance = createInstance(); - var disposable = instance as IDisposable; - if (disposable != null) - { - TrackInstance(scope, disposable); - } - - return instance; - } - - private static void TrackInstance(Scope scope, IDisposable disposable) - { - if (scope == null) - { - throw new InvalidOperationException("Attempt to create a disposable instance without a current scope."); - } - - scope.TrackInstance(disposable); - } - } - - /// - /// Ensures that only one service instance can exist within a given . - /// - /// - /// If the service instance implements , - /// it will be disposed when the ends. - /// - [System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage] - internal class PerScopeLifetime : ILifetime - { - private readonly ThreadSafeDictionary instances = new ThreadSafeDictionary(); - - /// - /// Returns the same service instance within the current . - /// - /// The function delegate used to create a new service instance. - /// The of the current service request. - /// The requested services instance. - public object GetInstance(Func createInstance, Scope scope) - { - if (scope == null) - { - throw new InvalidOperationException( - "Attempt to create a scoped instance without a current scope."); - } - - return instances.GetOrAdd(scope, s => CreateScopedInstance(s, createInstance)); - } - - private static void RegisterForDisposal(Scope scope, object instance) - { - var disposable = instance as IDisposable; - if (disposable != null) - { - scope.TrackInstance(disposable); - } - } - - private object CreateScopedInstance(Scope scope, Func createInstance) - { - scope.Completed += OnScopeCompleted; - var instance = createInstance(); - - RegisterForDisposal(scope, instance); - return instance; - } - - private void OnScopeCompleted(object sender, EventArgs e) - { - var scope = (Scope)sender; - scope.Completed -= OnScopeCompleted; - object removedInstance; - instances.TryRemove(scope, out removedInstance); - } - } - - /// - /// Manages a set of instances. - /// - [System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage] - internal class ScopeManager - { - private readonly object syncRoot = new object(); - - private Scope currentScope; - - /// - /// Gets the current . - /// - public Scope CurrentScope - { - get - { - lock (syncRoot) - { - return currentScope; - } - } - } - - /// - /// Starts a new . - /// - /// A new . - public Scope BeginScope() - { - lock (syncRoot) - { - var scope = new Scope(this, currentScope); - if (currentScope != null) - { - currentScope.ChildScope = scope; - } - - currentScope = scope; - return scope; - } - } - - /// - /// Ends the given and updates the property. - /// - /// The scope that is completed. - public void EndScope(Scope scope) - { - lock (syncRoot) - { - if (scope.ChildScope != null) - { - throw new InvalidOperationException("Attempt to end a scope before all child scopes are completed."); - } - - currentScope = scope.ParentScope; - if (currentScope != null) - { - currentScope.ChildScope = null; - } - } - } - } - - /// - /// Represents a scope. - /// - [System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage] - internal class Scope : IDisposable - { - private readonly IList disposableObjects = new List(); - - private readonly ScopeManager scopeManager; - - /// - /// Initializes a new instance of the class. - /// - /// The that manages this . - /// The parent . - public Scope(ScopeManager scopeManager, Scope parentScope) - { - this.scopeManager = scopeManager; - ParentScope = parentScope; - } - - /// - /// Raised when the is completed. - /// - public event EventHandler Completed; - - /// - /// Gets or sets the parent . - /// - public Scope ParentScope { get; internal set; } - - /// - /// Gets or sets the child . - /// - public Scope ChildScope { get; internal set; } - - /// - /// Registers the so that it is disposed when the scope is completed. - /// - /// The object to register. - public void TrackInstance(IDisposable disposable) - { - disposableObjects.Add(disposable); - } - - /// - /// Disposes all instances tracked by this scope. - /// - public void Dispose() - { - DisposeTrackedInstances(); - OnCompleted(); - } - - private void DisposeTrackedInstances() - { - foreach (var disposableObject in disposableObjects) - { - disposableObject.Dispose(); - } - } - - private void OnCompleted() - { - scopeManager.EndScope(this); - var completedHandler = Completed; - if (completedHandler != null) - { - completedHandler(this, new EventArgs()); - } - } - } - - /// - /// Used at the assembly level to describe the composition root(s) for the target assembly. - /// - [AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)] - [System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage] - internal class CompositionRootTypeAttribute : Attribute - { - /// - /// Initializes a new instance of the class. - /// - /// A that implements the interface. - public CompositionRootTypeAttribute(Type compositionRootType) - { - CompositionRootType = compositionRootType; - } - - /// - /// Gets the that implements the interface. - /// - public Type CompositionRootType { get; private set; } - } - - /// - /// Extracts concrete implementations from an . - /// - [System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage] - internal class CompositionRootTypeExtractor : ITypeExtractor - { - /// - /// Extracts concrete implementations found in the given . - /// - /// The for which to extract types. - /// A set of concrete implementations found in the given . - public Type[] Execute(Assembly assembly) - { - CompositionRootTypeAttribute[] compositionRootAttributes = - assembly.GetCustomAttributes(typeof(CompositionRootTypeAttribute)) - .Cast().ToArray(); - - if (compositionRootAttributes.Length > 0) - { - return compositionRootAttributes.Select(a => a.CompositionRootType).ToArray(); - } - - return assembly.GetTypes().Where(t => !t.IsAbstract() && typeof(ICompositionRoot).IsAssignableFrom(t)).ToArray(); - } - } - - /// - /// A cache decorator. - /// - [System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage] - internal class CachedTypeExtractor : ITypeExtractor - { - private readonly ITypeExtractor typeExtractor; - - private readonly ThreadSafeDictionary cache = - new ThreadSafeDictionary(); - - /// - /// Initializes a new instance of the class. - /// - /// The target . - public CachedTypeExtractor(ITypeExtractor typeExtractor) - { - this.typeExtractor = typeExtractor; - } - - /// - /// Extracts types found in the given . - /// - /// The for which to extract types. - /// A set of types found in the given . - public Type[] Execute(Assembly assembly) - { - return cache.GetOrAdd(assembly, typeExtractor.Execute); - } - } - - /// - /// Extracts concrete types from an . - /// - [System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage] - internal class ConcreteTypeExtractor : ITypeExtractor - { - private static readonly List InternalTypes = new List(); - - static ConcreteTypeExtractor() - { - InternalTypes.Add(typeof(LambdaConstructionInfoBuilder)); - InternalTypes.Add(typeof(ConstructorDependency)); - InternalTypes.Add(typeof(PropertyDependency)); - InternalTypes.Add(typeof(ThreadSafeDictionary<,>)); - InternalTypes.Add(typeof(Scope)); - InternalTypes.Add(typeof(PerContainerLifetime)); - InternalTypes.Add(typeof(PerScopeLifetime)); - InternalTypes.Add(typeof(ScopeManager)); - InternalTypes.Add(typeof(ServiceRegistration)); - InternalTypes.Add(typeof(DecoratorRegistration)); - InternalTypes.Add(typeof(ServiceRequest)); - InternalTypes.Add(typeof(Registration)); - InternalTypes.Add(typeof(ServiceContainer)); - InternalTypes.Add(typeof(ConstructionInfo)); - InternalTypes.Add(typeof(AssemblyLoader)); - InternalTypes.Add(typeof(TypeConstructionInfoBuilder)); - InternalTypes.Add(typeof(ConstructionInfoProvider)); - InternalTypes.Add(typeof(ConstructionInfoBuilder)); - InternalTypes.Add(typeof(MostResolvableConstructorSelector)); - InternalTypes.Add(typeof(PerContainerLifetime)); - InternalTypes.Add(typeof(PerContainerLifetime)); - InternalTypes.Add(typeof(PerRequestLifeTime)); - InternalTypes.Add(typeof(PropertySelector)); - InternalTypes.Add(typeof(AssemblyScanner)); - InternalTypes.Add(typeof(ConstructorDependencySelector)); - InternalTypes.Add(typeof(PropertyDependencySelector)); - InternalTypes.Add(typeof(CompositionRootTypeAttribute)); - InternalTypes.Add(typeof(ConcreteTypeExtractor)); - InternalTypes.Add(typeof(CompositionRootExecutor)); - InternalTypes.Add(typeof(CompositionRootTypeExtractor)); - InternalTypes.Add(typeof(CachedTypeExtractor)); - InternalTypes.Add(typeof(ImmutableList<>)); - InternalTypes.Add(typeof(KeyValue<,>)); - InternalTypes.Add(typeof(ImmutableHashTree<,>)); - InternalTypes.Add(typeof(PerThreadScopeManagerProvider)); - InternalTypes.Add(typeof(Emitter)); - InternalTypes.Add(typeof(Instruction)); - InternalTypes.Add(typeof(Instruction<>)); - InternalTypes.Add(typeof(PerLogicalCallContextScopeManagerProvider)); - InternalTypes.Add(typeof(LogicalThreadStorage<>)); - } - - /// - /// Extracts concrete types found in the given . - /// - /// The for which to extract types. - /// A set of concrete types found in the given . - public Type[] Execute(Assembly assembly) - { - return assembly.GetTypes().Where(t => t.IsClass() - && !t.IsNestedPrivate() - && !t.IsAbstract() - && !Equals(t.GetAssembly(), typeof(string).GetAssembly()) - && !IsCompilerGenerated(t)).Except(InternalTypes).ToArray(); - } - - private static bool IsCompilerGenerated(Type type) - { - return type.IsDefined(typeof(CompilerGeneratedAttribute), false); - } - } - - /// - /// A class that is responsible for instantiating and executing an . - /// - [System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage] - internal class CompositionRootExecutor : ICompositionRootExecutor - { - private readonly IServiceRegistry serviceRegistry; - - private readonly IList executedCompositionRoots = new List(); - - private readonly object syncRoot = new object(); - - /// - /// Initializes a new instance of the class. - /// - /// The to be configured by the . - public CompositionRootExecutor(IServiceRegistry serviceRegistry) - { - this.serviceRegistry = serviceRegistry; - } - - /// - /// Creates an instance of the and executes the method. - /// - /// The concrete type to be instantiated and executed. - public void Execute(Type compositionRootType) - { - if (!executedCompositionRoots.Contains(compositionRootType)) - { - lock (syncRoot) - { - if (!executedCompositionRoots.Contains(compositionRootType)) - { - executedCompositionRoots.Add(compositionRootType); - var compositionRoot = (ICompositionRoot)Activator.CreateInstance(compositionRootType); - compositionRoot.Compose(serviceRegistry); - } - } - } - } - } - - /// - /// An assembly scanner that registers services based on the types contained within an . - /// - [System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage] - internal class AssemblyScanner : IAssemblyScanner - { - private readonly ITypeExtractor concreteTypeExtractor; - private readonly ITypeExtractor compositionRootTypeExtractor; - private readonly ICompositionRootExecutor compositionRootExecutor; - private Assembly currentAssembly; - - /// - /// Initializes a new instance of the class. - /// - /// The that is responsible for - /// extracting concrete types from the assembly being scanned. - /// The that is responsible for - /// extracting implementations from the assembly being scanned. - /// The that is - /// responsible for creating and executing an . - public AssemblyScanner(ITypeExtractor concreteTypeExtractor, ITypeExtractor compositionRootTypeExtractor, ICompositionRootExecutor compositionRootExecutor) - { - this.concreteTypeExtractor = concreteTypeExtractor; - this.compositionRootTypeExtractor = compositionRootTypeExtractor; - this.compositionRootExecutor = compositionRootExecutor; - } - - /// - /// Scans the target and registers services found within the assembly. - /// - /// The to scan. - /// The target instance. - /// The factory that controls the lifetime of the registered service. - /// A function delegate that determines if a service implementation should be registered. - public void Scan(Assembly assembly, IServiceRegistry serviceRegistry, Func lifetimeFactory, Func shouldRegister) - { - Type[] concreteTypes = GetConcreteTypes(assembly); - foreach (Type type in concreteTypes) - { - BuildImplementationMap(type, serviceRegistry, lifetimeFactory, shouldRegister); - } - } - - /// - /// Scans the target and executes composition roots found within the . - /// - /// The to scan. - /// The target instance. - public void Scan(Assembly assembly, IServiceRegistry serviceRegistry) - { - Type[] compositionRootTypes = GetCompositionRootTypes(assembly); - if (compositionRootTypes.Length > 0 && !Equals(currentAssembly, assembly)) - { - currentAssembly = assembly; - ExecuteCompositionRoots(compositionRootTypes); - } - } - - private static string GetServiceName(Type serviceType, Type implementingType) - { - string implementingTypeName = implementingType.Name; - string serviceTypeName = serviceType.Name; - if (implementingType.IsGenericTypeDefinition()) - { - var regex = new Regex("((?:[a-z][a-z]+))", RegexOptions.IgnoreCase); - implementingTypeName = regex.Match(implementingTypeName).Groups[1].Value; - serviceTypeName = regex.Match(serviceTypeName).Groups[1].Value; - } - - if (serviceTypeName.Substring(1) == implementingTypeName) - { - implementingTypeName = string.Empty; - } - - return implementingTypeName; - } - - private static IEnumerable GetBaseTypes(Type concreteType) - { - Type baseType = concreteType; - while (baseType != typeof(object) && baseType != null) - { - yield return baseType; - baseType = baseType.GetBaseType(); - } - } - - private void ExecuteCompositionRoots(IEnumerable compositionRoots) - { - foreach (var compositionRoot in compositionRoots) - { - compositionRootExecutor.Execute(compositionRoot); - } - } - - private Type[] GetConcreteTypes(Assembly assembly) - { - return concreteTypeExtractor.Execute(assembly); - } - - private Type[] GetCompositionRootTypes(Assembly assembly) - { - return compositionRootTypeExtractor.Execute(assembly); - } - - private void BuildImplementationMap(Type implementingType, IServiceRegistry serviceRegistry, Func lifetimeFactory, Func shouldRegister) - { - Type[] interfaces = implementingType.GetInterfaces(); - foreach (Type interfaceType in interfaces) - { - if (shouldRegister(interfaceType, implementingType)) - { - RegisterInternal(interfaceType, implementingType, serviceRegistry, lifetimeFactory()); - } - } - - foreach (Type baseType in GetBaseTypes(implementingType)) - { - if (shouldRegister(baseType, implementingType)) - { - RegisterInternal(baseType, implementingType, serviceRegistry, lifetimeFactory()); - } - } - } - - private void RegisterInternal(Type serviceType, Type implementingType, IServiceRegistry serviceRegistry, ILifetime lifetime) - { - if (serviceType.IsGenericType() && serviceType.ContainsGenericParameters()) - { - serviceType = serviceType.GetGenericTypeDefinition(); - } - - serviceRegistry.Register(serviceType, implementingType, GetServiceName(serviceType, implementingType), lifetime); - } - } - - /// - /// Selects the properties that represents a dependency to the target . - /// - [System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage] - internal class PropertySelector : IPropertySelector - { - /// - /// Selects properties that represents a dependency from the given . - /// - /// The for which to select the properties. - /// A list of properties that represents a dependency to the target - public IEnumerable Execute(Type type) - { - return type.GetProperties().Where(IsInjectable).ToList(); - } - - /// - /// Determines if the represents an injectable property. - /// - /// The that describes the target property. - /// true if the property is injectable, otherwise false. - protected virtual bool IsInjectable(PropertyInfo propertyInfo) - { - return !IsReadOnly(propertyInfo); - } - - private static bool IsReadOnly(PropertyInfo propertyInfo) - { - return propertyInfo.GetSetMethod() == null || propertyInfo.GetSetMethod().IsStatic || propertyInfo.GetSetMethod().IsPrivate || propertyInfo.GetIndexParameters().Length > 0; - } - } - - /// - /// Loads all assemblies from the application base directory that matches the given search pattern. - /// - [System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage] - internal class AssemblyLoader : IAssemblyLoader - { - /// - /// Loads a set of assemblies based on the given . - /// - /// The search pattern to use. - /// A list of assemblies based on the given . - public IEnumerable Load(string searchPattern) - { - string directory = Path.GetDirectoryName(new Uri(typeof(ServiceContainer).Assembly.CodeBase).LocalPath); - if (directory != null) - { - string[] searchPatterns = searchPattern.Split('|'); - foreach (string file in searchPatterns.SelectMany(sp => Directory.GetFiles(directory, sp)).Where(CanLoad)) - { - yield return Assembly.LoadFrom(file); - } - } - } - - /// - /// Indicates if the current represent a file that can be loaded. - /// - /// The name of the target file. - /// true if the file can be loaded, otherwise false. - protected virtual bool CanLoad(string fileName) - { - return true; - } - } - - /// - /// Defines an immutable representation of a key and a value. - /// - /// The type of the key. - /// The type of the value. - internal sealed class KeyValue - { - /// - /// The key of this instance. - /// - public readonly TKey Key; - - /// - /// The key of this instance. - /// - public readonly TValue Value; - - /// - /// Initializes a new instance of the class. - /// - /// The key of this instance. - /// The value of this instance. - public KeyValue(TKey key, TValue value) - { - Key = key; - Value = value; - } - } - - /// - /// Represents a simple "add only" immutable list. - /// - /// The type of items contained in the list. - internal sealed class ImmutableList - { - /// - /// Represents an empty . - /// - public static readonly ImmutableList Empty = new ImmutableList(); - - /// - /// An array that contains the items in the . - /// - public readonly T[] Items; - - /// - /// The number of items in the . - /// - public readonly int Count; - - /// - /// Initializes a new instance of the class. - /// - /// The list from which the previous items are copied. - /// The value to be added to the list. - public ImmutableList(ImmutableList previousList, T value) - { - Items = new T[previousList.Items.Length + 1]; - Array.Copy(previousList.Items, Items, previousList.Items.Length); - Items[Items.Length - 1] = value; - Count = Items.Length; - } - - private ImmutableList() - { - Items = new T[0]; - } - - /// - /// Creates a new that contains the new . - /// - /// The value to be added to the new list. - /// A new that contains the new . - public ImmutableList Add(T value) - { - return new ImmutableList(this, value); - } - } - - /// - /// A balanced binary search tree implemented as an AVL tree. - /// - /// The type of the key. - /// The type of the value. - internal sealed class ImmutableHashTree - { - /// - /// An empty . - /// - public static readonly ImmutableHashTree Empty = new ImmutableHashTree(); - - /// - /// The key of this . - /// - public readonly TKey Key; - - /// - /// The value of this . - /// - public readonly TValue Value; - - /// - /// The list of instances where the - /// has the same hash code as this . - /// - public readonly ImmutableList> Duplicates; - - /// - /// The hash code retrieved from the . - /// - public readonly int HashCode; - - /// - /// The left node of this . - /// - public readonly ImmutableHashTree Left; - - /// - /// The right node of this . - /// - public readonly ImmutableHashTree Right; - - /// - /// The height of this node. - /// - /// - /// An empty node has a height of 0 and a node without children has a height of 1. - /// - public readonly int Height; - - /// - /// Indicates that this is empty. - /// - public readonly bool IsEmpty; - - /// - /// Initializes a new instance of the class - /// and adds a new entry in the list. - /// - /// The key for this node. - /// The value for this node. - /// The that contains existing duplicates. - public ImmutableHashTree(TKey key, TValue value, ImmutableHashTree hashTree) - { - Duplicates = hashTree.Duplicates.Add(new KeyValue(key, value)); - Key = hashTree.Key; - Value = hashTree.Value; - Height = hashTree.Height; - HashCode = hashTree.HashCode; - Left = hashTree.Left; - Right = hashTree.Right; - } - - /// - /// Initializes a new instance of the class. - /// - /// The key for this node. - /// The value for this node. - /// The left node. - /// The right node. - public ImmutableHashTree(TKey key, TValue value, ImmutableHashTree left, ImmutableHashTree right) - { - var balance = left.Height - right.Height; - - if (balance == -2) - { - if (right.IsLeftHeavy()) - { - right = RotateRight(right); - } - - // Rotate left - Key = right.Key; - Value = right.Value; - Left = new ImmutableHashTree(key, value, left, right.Left); - Right = right.Right; - } - else if (balance == 2) - { - if (left.IsRightHeavy()) - { - left = RotateLeft(left); - } - - // Rotate right - Key = left.Key; - Value = left.Value; - Right = new ImmutableHashTree(key, value, left.Right, right); - Left = left.Left; - } - else - { - Key = key; - Value = value; - Left = left; - Right = right; - } - - Height = 1 + Math.Max(Left.Height, Right.Height); - - Duplicates = ImmutableList>.Empty; - - HashCode = Key.GetHashCode(); - } - - private ImmutableHashTree() - { - IsEmpty = true; - Duplicates = ImmutableList>.Empty; - } - - private static ImmutableHashTree RotateLeft(ImmutableHashTree left) - { - return new ImmutableHashTree( - left.Right.Key, - left.Right.Value, - new ImmutableHashTree(left.Key, left.Value, left.Right.Left, left.Left), - left.Right.Right); - } - - private static ImmutableHashTree RotateRight(ImmutableHashTree right) - { - return new ImmutableHashTree( - right.Left.Key, - right.Left.Value, - right.Left.Left, - new ImmutableHashTree(right.Key, right.Value, right.Left.Right, right.Right)); - } - - private bool IsLeftHeavy() - { - return Left.Height > Right.Height; - } - - private bool IsRightHeavy() - { - return Right.Height > Left.Height; - } - } - - /// - /// Represents an MSIL instruction to be emitted into a dynamic method. - /// - [System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage] - internal class Instruction - { - /// - /// Initializes a new instance of the class. - /// - /// The to be emitted. - /// The action to be performed against an - /// when this is emitted. - public Instruction(OpCode code, Action emitAction) - { - Code = code; - Emit = emitAction; - } - - /// - /// Gets the to be emitted. - /// - public OpCode Code { get; private set; } - - /// - /// Gets the action to be performed against an - /// when this is emitted. - /// - public Action Emit { get; private set; } - - /// - /// Returns the string representation of an . - /// - /// The string representation of an . - public override string ToString() - { - return Code.ToString(); - } - } - - /// - /// Represents an MSIL instruction to be emitted into a dynamic method. - /// - /// The type of argument used in this instruction. - [System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage] - internal class Instruction : Instruction - { - /// - /// Initializes a new instance of the class. - /// - /// The to be emitted. - /// The argument be passed along with the given . - /// The action to be performed against an - /// when this is emitted. - public Instruction(OpCode code, T argument, Action emitAction) - : base(code, emitAction) - { - Argument = argument; - } - - /// - /// Gets the argument be passed along with the given . - /// - public T Argument { get; private set; } - - /// - /// Returns the string representation of an . - /// - /// The string representation of an . - public override string ToString() - { - return base.ToString() + " " + Argument; - } - } - - /// - /// An abstraction of the class that provides information - /// about the currently on the stack. - /// - [System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage] - internal class Emitter : IEmitter - { - private readonly ILGenerator generator; - - private readonly Type[] parameterTypes; - - private readonly Stack stack = new Stack(); - - private readonly List variables = new List(); - - private readonly List instructions = new List(); - - /// - /// Initializes a new instance of the class. - /// - /// The used to emit MSIL instructions. - /// The list of parameter types used by the current dynamic method. - public Emitter(ILGenerator generator, Type[] parameterTypes) - { - this.generator = generator; - this.parameterTypes = parameterTypes; - } - - /// - /// Gets the currently on the stack. - /// - public Type StackType - { - get - { - return stack.Count == 0 ? null : stack.Peek(); - } - } - - /// - /// Gets a list containing each to be emitted into the dynamic method. - /// - public List Instructions - { - get - { - return instructions; - } - } - - /// - /// Puts the specified instruction onto the stream of instructions. - /// - /// The Microsoft Intermediate Language (MSIL) instruction to be put onto the stream. - public void Emit(OpCode code) - { - if (code == OpCodes.Ldarg_0) - { - stack.Push(parameterTypes[0]); - } - else if (code == OpCodes.Ldarg_1) - { - stack.Push(parameterTypes[1]); - } - else if (code == OpCodes.Ldarg_2) - { - stack.Push(parameterTypes[2]); - } - else if (code == OpCodes.Ldarg_3) - { - stack.Push(parameterTypes[3]); - } - else if (code == OpCodes.Ldloc_0) - { - stack.Push(variables[0].LocalType); - } - else if (code == OpCodes.Ldloc_1) - { - stack.Push(variables[1].LocalType); - } - else if (code == OpCodes.Ldloc_2) - { - stack.Push(variables[2].LocalType); - } - else if (code == OpCodes.Ldloc_3) - { - stack.Push(variables[3].LocalType); - } - else if (code == OpCodes.Stloc_0) - { - stack.Pop(); - } - else if (code == OpCodes.Stloc_1) - { - stack.Pop(); - } - else if (code == OpCodes.Stloc_2) - { - stack.Pop(); - } - else if (code == OpCodes.Stloc_3) - { - stack.Pop(); - } - else if (code == OpCodes.Ldelem_Ref) - { - stack.Pop(); - Type arrayType = stack.Pop(); - stack.Push(arrayType.GetElementType()); - } - else if (code == OpCodes.Ldlen) - { - stack.Pop(); - stack.Push(typeof(int)); - } - else if (code == OpCodes.Conv_I4) - { - stack.Pop(); - stack.Push(typeof(int)); - } - else if (code == OpCodes.Ldc_I4_0) - { - stack.Push(typeof(int)); - } - else if (code == OpCodes.Ldc_I4_1) - { - stack.Push(typeof(int)); - } - else if (code == OpCodes.Ldc_I4_2) - { - stack.Push(typeof(int)); - } - else if (code == OpCodes.Ldc_I4_3) - { - stack.Push(typeof(int)); - } - else if (code == OpCodes.Ldc_I4_4) - { - stack.Push(typeof(int)); - } - else if (code == OpCodes.Ldc_I4_5) - { - stack.Push(typeof(int)); - } - else if (code == OpCodes.Ldc_I4_6) - { - stack.Push(typeof(int)); - } - else if (code == OpCodes.Ldc_I4_7) - { - stack.Push(typeof(int)); - } - else if (code == OpCodes.Ldc_I4_8) - { - stack.Push(typeof(int)); - } - else if (code == OpCodes.Sub) - { - stack.Pop(); - stack.Pop(); - stack.Push(typeof(int)); - } - else if (code == OpCodes.Ret) - { - } - else - { - throw new NotSupportedException(code.ToString()); - } - - instructions.Add(new Instruction(code, il => il.Emit(code))); - if (code == OpCodes.Ret) - { - foreach (var instruction in instructions) - { - instruction.Emit(generator); - } - } - } - - /// - /// Puts the specified instruction and numerical argument onto the Microsoft intermediate language (MSIL) stream of instructions. - /// - /// The MSIL instruction to be put onto the stream. - /// The numerical argument pushed onto the stream immediately after the instruction. - public void Emit(OpCode code, int arg) - { - if (code == OpCodes.Ldc_I4) - { - stack.Push(typeof(int)); - } - else if (code == OpCodes.Ldarg) - { - stack.Push(parameterTypes[arg]); - } - else if (code == OpCodes.Ldloc) - { - stack.Push(variables[arg].LocalType); - } - else if (code == OpCodes.Stloc) - { - stack.Pop(); - } - else - { - throw new NotSupportedException(code.ToString()); - } - - instructions.Add(new Instruction(code, arg, il => il.Emit(code, arg))); - } - - /// - /// Puts the specified instruction and numerical argument onto the Microsoft intermediate language (MSIL) stream of instructions. - /// - /// The MSIL instruction to be put onto the stream. - /// The numerical argument pushed onto the stream immediately after the instruction. - public void Emit(OpCode code, sbyte arg) - { - if (code == OpCodes.Ldc_I4_S) - { - stack.Push(typeof(sbyte)); - } - else - { - throw new NotSupportedException(code.ToString()); - } - - instructions.Add(new Instruction(code, arg, il => il.Emit(code, arg))); - } - - /// - /// Puts the specified instruction and numerical argument onto the Microsoft intermediate language (MSIL) stream of instructions. - /// - /// The MSIL instruction to be put onto the stream. - /// The numerical argument pushed onto the stream immediately after the instruction. - public void Emit(OpCode code, byte arg) - { - if (code == OpCodes.Ldloc_S) - { - stack.Push(variables[arg].LocalType); - } - else if (code == OpCodes.Ldarg_S) - { - stack.Push(parameterTypes[arg]); - } - else if (code == OpCodes.Stloc_S) - { - stack.Pop(); - } - else - { - throw new NotSupportedException(code.ToString()); - } - - instructions.Add(new Instruction(code, arg, il => il.Emit(code, arg))); - } - - /// - /// Puts the specified instruction onto the Microsoft intermediate language (MSIL) stream followed by the metadata token for the given type. - /// - /// The MSIL instruction to be put onto the stream. - /// A representing the type metadata token. - public void Emit(OpCode code, Type type) - { - if (code == OpCodes.Newarr) - { - stack.Pop(); - stack.Push(type.MakeArrayType()); - } - else if (code == OpCodes.Stelem) - { - stack.Pop(); - stack.Pop(); - stack.Pop(); - } - else if (code == OpCodes.Castclass) - { - stack.Pop(); - stack.Push(type); - } - else if (code == OpCodes.Box) - { - stack.Pop(); - stack.Push(typeof(object)); - } - else if (code == OpCodes.Unbox_Any) - { - stack.Pop(); - stack.Push(type); - } - else - { - throw new NotSupportedException(code.ToString()); - } - - instructions.Add(new Instruction(code, type, il => il.Emit(code, type))); - } - - /// - /// Puts the specified instruction and metadata token for the specified constructor onto the Microsoft intermediate language (MSIL) stream of instructions. - /// - /// The MSIL instruction to be emitted onto the stream. - /// A representing a constructor. - public void Emit(OpCode code, ConstructorInfo constructor) - { - if (code == OpCodes.Newobj) - { - var parameterCount = constructor.GetParameters().Length; - for (int i = 0; i < parameterCount; i++) - { - stack.Pop(); - } - - stack.Push(constructor.DeclaringType); - } - else - { - throw new NotSupportedException(code.ToString()); - } - - instructions.Add(new Instruction(code, constructor, il => il.Emit(code, constructor))); - } - - /// - /// Puts the specified instruction onto the Microsoft intermediate language (MSIL) stream followed by the index of the given local variable. - /// - /// The MSIL instruction to be emitted onto the stream. - /// A local variable. - public void Emit(OpCode code, LocalBuilder localBuilder) - { - if (code == OpCodes.Stloc) - { - stack.Pop(); - } - else if (code == OpCodes.Ldloc) - { - stack.Push(localBuilder.LocalType); - } - else - { - throw new NotSupportedException(code.ToString()); - } - - instructions.Add(new Instruction(code, localBuilder, il => il.Emit(code, localBuilder))); - } - - /// - /// Puts the specified instruction onto the Microsoft intermediate language (MSIL) stream followed by the metadata token for the given method. - /// - /// The MSIL instruction to be emitted onto the stream. - /// A representing a method. - public void Emit(OpCode code, MethodInfo methodInfo) - { - if (code == OpCodes.Callvirt || code == OpCodes.Call) - { - var parameterCount = methodInfo.GetParameters().Length; - for (int i = 0; i < parameterCount; i++) - { - stack.Pop(); - } - - if (!methodInfo.IsStatic) - { - stack.Pop(); - } - - if (methodInfo.ReturnType != typeof(void)) - { - stack.Push(methodInfo.ReturnType); - } - } - else - { - throw new NotSupportedException(code.ToString()); - } - - instructions.Add(new Instruction(code, methodInfo, il => il.Emit(code, methodInfo))); - } - - /// - /// Declares a local variable of the specified type. - /// - /// A object that represents the type of the local variable. - /// The declared local variable. - public LocalBuilder DeclareLocal(Type type) - { - var localBuilder = generator.DeclareLocal(type); - variables.Add(localBuilder); - return localBuilder; - } - } - - /// - /// Provides storage per logical thread of execution. - /// - /// The type of the value contained in this . - [System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage] - internal class LogicalThreadStorage - { - private readonly Func valueFactory; - - private readonly string key; - - private readonly object lockObject = new object(); - - /// - /// Initializes a new instance of the class. - /// - /// The value factory used to create an instance of . - public LogicalThreadStorage(Func valueFactory) - { - this.valueFactory = valueFactory; - key = Guid.NewGuid().ToString(); - } - - /// - /// Gets the value for the current logical thread of execution. - /// - /// - /// The value for the current logical thread of execution. - /// - public T Value - { - get - { - var holder = (LogicalThreadValue)CallContext.LogicalGetData(key); - if (holder != null) - { - return holder.Value; - } - - lock (lockObject) - { - holder = (LogicalThreadValue)CallContext.LogicalGetData(key); - if (holder == null) - { - holder = new LogicalThreadValue { Value = valueFactory() }; - CallContext.LogicalSetData(key, holder); - } - } - - return holder.Value; - } - } - - [Serializable] - private class LogicalThreadValue : MarshalByRefObject - { - [NonSerialized] - private T value; - - public T Value - { - get - { - return value; - } - - set - { - this.value = value; - } - } - } - } -} \ No newline at end of file diff --git a/src/Umbraco.Core/LightInject/LightInjectExtensions.cs b/src/Umbraco.Core/LightInject/LightInjectExtensions.cs deleted file mode 100644 index f2900b58c9..0000000000 --- a/src/Umbraco.Core/LightInject/LightInjectExtensions.cs +++ /dev/null @@ -1,1015 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Globalization; -using System.Linq; -using System.Linq.Expressions; -using System.Reflection; -using System.Text; -using System.Threading.Tasks; - -namespace Umbraco.Core.LightInject -{ - internal static class LightInjectExtensions - { - /// - /// In order for LightInject to deal with enumerables of the same type, each one needs to be named individually - /// - /// - /// - /// - /// - public static void RegisterCollection(this IServiceContainer container, IEnumerable implementationTypes) - where TLifetime : ILifetime - { - var i = 0; - foreach (var type in implementationTypes) - { - //This works as of 3.0.2.2: https://github.com/seesharper/LightInject/issues/68#issuecomment-70611055 - // but means that the explicit type is registered, not the implementing type - container.Register(type, Activator.CreateInstance()); - - //NOTE: This doesn't work, but it would be nice if it did (autofac supports thsi) - //container.Register(typeof(TService), type, - // Activator.CreateInstance()); - - //This does work, but requires a unique name per service - //container.Register(typeof(TService), type, - // //need to name it, we'll keep the name tiny - // i.ToString(CultureInfo.InvariantCulture), - // Activator.CreateInstance()); - //i++; - } - } - - /// - /// In order for LightInject to deal with enumerables of the same type, each one needs to be named individually - /// - /// - /// - /// - public static void RegisterCollection(this IServiceContainer container, IEnumerable implementationTypes) - { - var i = 0; - foreach (var type in implementationTypes) - { - //This works as of 3.0.2.2: https://github.com/seesharper/LightInject/issues/68#issuecomment-70611055 - // but means that the explicit type is registered, not the implementing type - container.Register(type); - - //NOTE: This doesn't work, but it would be nice if it did (autofac supports thsi) - //container.Register(typeof(TService), type); - - //This does work, but requires a unique name per service - //container.Register(typeof(TService), type, - // //need to name it, we'll keep the name tiny - // i.ToString(CultureInfo.InvariantCulture)); - //i++; - } - } - - /// - /// Creates a child container from the parent container - /// - /// - /// - public static ServiceContainer CreateChildContainer(this IServiceContainer parentContainer) - { - var child = new ChildContainer(parentContainer); - return child; - } - - private class ChildContainer : ServiceContainer - { - public ChildContainer(IServiceRegistry parentContainer) - { - foreach (var svc in parentContainer.AvailableServices) - { - Register(svc); - } - } - } - - ///// - ///// A container wrapper for 2 containers: Child and Parent - ///// - //private class ChildContainer : IServiceContainer - //{ - // private readonly IServiceContainer _parent; - // private readonly IServiceContainer _current = new ServiceContainer(); - - // public ChildContainer(IServiceContainer parent) - // { - // _parent = parent; - // } - - // /// - // /// Gets a list of instances that represents the - // /// registered services. - // /// - // public IEnumerable AvailableServices - // { - // get { return _current.AvailableServices.Union(_parent.AvailableServices); } - // } - - // /// - // /// Registers the with the . - // /// - // /// The service type to register. - // /// The implementing type. - // public void Register(Type serviceType, Type implementingType) - // { - // _current.Register(serviceType, implementingType); - // } - - // /// - // /// Registers the with the . - // /// - // /// The service type to register. - // /// The implementing type. - // /// The instance that controls the lifetime of the registered service. - // public void Register(Type serviceType, Type implementingType, ILifetime lifetime) - // { - // _current.Register(serviceType, implementingType, lifetime); - // } - - // /// - // /// Registers the with the . - // /// - // /// The service type to register. - // /// The implementing type. - // /// The name of the service. - // public void Register(Type serviceType, Type implementingType, string serviceName) - // { - // _current.Register(serviceType, implementingType, serviceName); - // } - - // /// - // /// Registers the with the . - // /// - // /// The service type to register. - // /// The implementing type. - // /// The name of the service. - // /// The instance that controls the lifetime of the registered service. - // public void Register(Type serviceType, Type implementingType, string serviceName, ILifetime lifetime) - // { - // _current.Register(serviceType, implementingType, serviceName, lifetime); - // } - - // /// - // /// Registers the with the . - // /// - // /// The service type to register. - // /// The implementing type. - // public void Register() where TImplementation : TService - // { - // _current.Register(); - // } - - // /// - // /// Registers the with the . - // /// - // /// The service type to register. - // /// The implementing type. - // /// The instance that controls the lifetime of the registered service. - // public void Register(ILifetime lifetime) where TImplementation : TService - // { - // _current.Register(lifetime); - // } - - // /// - // /// Registers the with the . - // /// - // /// The service type to register. - // /// The implementing type. - // /// The name of the service. - // public void Register(string serviceName) where TImplementation : TService - // { - // _current.Register(serviceName); - // } - - // /// - // /// Registers the with the . - // /// - // /// The service type to register. - // /// The implementing type. - // /// The name of the service. - // /// The instance that controls the lifetime of the registered service. - // public void Register(string serviceName, ILifetime lifetime) where TImplementation : TService - // { - // _current.Register(serviceName, lifetime); - // } - - // /// - // /// Registers the with the given . - // /// - // /// The service type to register. - // /// The instance returned when this service is requested. - // public void RegisterInstance(TService instance) - // { - // _current.RegisterInstance(instance); - // } - - // /// - // /// Registers the with the given . - // /// - // /// The service type to register. - // /// The instance returned when this service is requested. - // /// The name of the service. - // public void RegisterInstance(TService instance, string serviceName) - // { - // _current.RegisterInstance(instance, serviceName); - // } - - // /// - // /// Registers the with the given . - // /// - // /// The service type to register. - // /// The instance returned when this service is requested. - // public void RegisterInstance(Type serviceType, object instance) - // { - // _current.RegisterInstance(serviceType, instance); - // } - - // /// - // /// Registers the with the given . - // /// - // /// The service type to register. - // /// The instance returned when this service is requested. - // /// The name of the service. - // public void RegisterInstance(Type serviceType, object instance, string serviceName) - // { - // _current.RegisterInstance(serviceType, instance, serviceName); - // } - - // /// - // /// Registers a concrete type as a service. - // /// - // /// The service type to register. - // public void Register() - // { - // _current.Register(); - // } - - // /// - // /// Registers a concrete type as a service. - // /// - // /// The service type to register. - // /// The instance that controls the lifetime of the registered service. - // public void Register(ILifetime lifetime) - // { - // _current.Register(lifetime); - // } - - // /// - // /// Registers a concrete type as a service. - // /// - // /// The concrete type to register. - // public void Register(Type serviceType) - // { - // _current.Register(serviceType); - // } - - // /// - // /// Registers a concrete type as a service. - // /// - // /// The concrete type to register. - // /// The instance that controls the lifetime of the registered service. - // public void Register(Type serviceType, ILifetime lifetime) - // { - // _current.Register(serviceType, lifetime); - // } - - // /// - // /// Registers the with the that - // /// describes the dependencies of the service. - // /// - // /// The service type to register. - // /// A factory delegate used to create the instance. - // public void Register(Expression> factory) - // { - // _current.Register(factory); - // } - - // /// - // /// Registers the with the that - // /// describes the dependencies of the service. - // /// - // /// The parameter type. - // /// The service type to register. - // /// A factory delegate used to create the instance. - // public void Register(Expression> factory) - // { - // _current.Register(factory); - // } - - // /// - // /// Registers the with the that - // /// describes the dependencies of the service. - // /// - // /// The parameter type. - // /// The service type to register. - // /// A factory delegate used to create the instance. - // /// The name of the service. - // public void Register(Expression> factory, string serviceName) - // { - // _current.Register(factory, serviceName); - // } - - // /// - // /// Registers the with the that - // /// describes the dependencies of the service. - // /// - // /// The type of the first parameter. - // /// The type of the second parameter. - // /// The service type to register. - // /// A factory delegate used to create the instance. - // public void Register(Expression> factory) - // { - // _current.Register(factory); - // } - - // /// - // /// Registers the with the that - // /// describes the dependencies of the service. - // /// - // /// The type of the first parameter. - // /// The type of the second parameter. - // /// The service type to register. - // /// A factory delegate used to create the instance. - // /// The name of the service. - // public void Register(Expression> factory, string serviceName) - // { - // _current.Register(factory, serviceName); - // } - - // /// - // /// Registers the with the that - // /// describes the dependencies of the service. - // /// - // /// The type of the first parameter. - // /// The type of the second parameter. - // /// The type of the third parameter. - // /// The service type to register. - // /// A factory delegate used to create the instance. - // public void Register(Expression> factory) - // { - // _current.Register(factory); - // } - - // /// - // /// Registers the with the that - // /// describes the dependencies of the service. - // /// - // /// The type of the first parameter. - // /// The type of the second parameter. - // /// The type of the third parameter. - // /// The service type to register. - // /// A factory delegate used to create the instance. - // /// The name of the service. - // public void Register(Expression> factory, string serviceName) - // { - // _current.Register(factory, serviceName); - // } - - // /// - // /// Registers the with the that - // /// describes the dependencies of the service. - // /// - // /// The type of the first parameter. - // /// The type of the second parameter. - // /// The type of the third parameter. - // /// The type of the fourth parameter. - // /// The service type to register. - // /// A factory delegate used to create the instance. - // public void Register(Expression> factory) - // { - // _current.Register(factory); - // } - - // /// - // /// Registers the with the that - // /// describes the dependencies of the service. - // /// - // /// The type of the first parameter. - // /// The type of the second parameter. - // /// The type of the third parameter. - // /// The type of the fourth parameter. - // /// The service type to register. - // /// A factory delegate used to create the instance. - // /// The name of the service. - // public void Register(Expression> factory, string serviceName) - // { - // _current.Register(factory, serviceName); - // } - - // /// - // /// Registers the with the that - // /// describes the dependencies of the service. - // /// - // /// The service type to register. - // /// The lambdaExpression that describes the dependencies of the service. - // /// The instance that controls the lifetime of the registered service. - // public void Register(Expression> factory, ILifetime lifetime) - // { - // _current.Register(factory, lifetime); - // } - - // /// - // /// Registers the with the that - // /// describes the dependencies of the service. - // /// - // /// The service type to register. - // /// The lambdaExpression that describes the dependencies of the service. - // /// The name of the service. - // public void Register(Expression> factory, string serviceName) - // { - // _current.Register(factory, serviceName); - // } - - // /// - // /// Registers the with the that - // /// describes the dependencies of the service. - // /// - // /// The service type to register. - // /// The lambdaExpression that describes the dependencies of the service. - // /// The name of the service. - // /// The instance that controls the lifetime of the registered service. - // public void Register(Expression> factory, string serviceName, ILifetime lifetime) - // { - // _current.Register(factory, serviceName, lifetime); - // } - - // /// - // /// Registers a custom factory delegate used to create services that is otherwise unknown to the service container. - // /// - // /// Determines if the service can be created by the delegate. - // /// Creates a service instance according to the predicate. - // public void RegisterFallback(Func predicate, Func factory) - // { - // _current.RegisterFallback(predicate, factory); - // } - - // /// - // /// Registers a custom factory delegate used to create services that is otherwise unknown to the service container. - // /// - // /// Determines if the service can be created by the delegate. - // /// Creates a service instance according to the predicate. - // /// The instance that controls the lifetime of the registered service. - // public void RegisterFallback(Func predicate, Func factory, ILifetime lifetime) - // { - // _current.RegisterFallback(predicate, factory, lifetime); - // } - - // /// - // /// Registers a service based on a instance. - // /// - // /// The instance that contains service metadata. - // public void Register(ServiceRegistration serviceRegistration) - // { - // _current.Register(serviceRegistration); - // } - - // /// - // /// Registers composition roots from the given . - // /// - // /// The assembly to be scanned for services. - // /// - // /// If the target contains an implementation of the interface, this - // /// will be used to configure the container. - // /// - // public void RegisterAssembly(Assembly assembly) - // { - // _current.RegisterAssembly(assembly); - // } - - // /// - // /// Registers services from the given . - // /// - // /// The assembly to be scanned for services. - // /// A function delegate that determines if a service implementation should be registered. - // /// - // /// If the target contains an implementation of the interface, this - // /// will be used to configure the container. - // /// - // public void RegisterAssembly(Assembly assembly, Func shouldRegister) - // { - // _current.RegisterAssembly(assembly, shouldRegister); - // } - - // /// - // /// Registers services from the given . - // /// - // /// The assembly to be scanned for services. - // /// The instance that controls the lifetime of the registered service. - // /// - // /// If the target contains an implementation of the interface, this - // /// will be used to configure the container. - // /// - // public void RegisterAssembly(Assembly assembly, Func lifetime) - // { - // _current.RegisterAssembly(assembly, lifetime); - // } - - // /// - // /// Registers services from the given . - // /// - // /// The assembly to be scanned for services. - // /// The factory that controls the lifetime of the registered service. - // /// A function delegate that determines if a service implementation should be registered. - // /// - // /// If the target contains an implementation of the interface, this - // /// will be used to configure the container. - // /// - // public void RegisterAssembly(Assembly assembly, Func lifetimeFactory, Func shouldRegister) - // { - // _current.RegisterAssembly(assembly, lifetimeFactory, shouldRegister); - // } - - // /// - // /// Registers services from the given type. - // /// - // /// The type of to register from. - // public void RegisterFrom() where TCompositionRoot : ICompositionRoot, new() - // { - // _current.RegisterFrom(); - // } - - // /// - // /// Registers composition roots from assemblies in the base directory that matches the . - // /// - // /// The search pattern used to filter the assembly files. - // public void RegisterAssembly(string searchPattern) - // { - // _current.RegisterAssembly(searchPattern); - // } - - // /// - // /// Decorates the with the given . - // /// - // /// The target service type. - // /// The decorator type used to decorate the . - // /// A function delegate that determines if the - // /// should be applied to the target . - // public void Decorate(Type serviceType, Type decoratorType, Func predicate) - // { - // _current.Decorate(serviceType, decoratorType, predicate); - // } - - // /// - // /// Decorates the with the given . - // /// - // /// The target service type. - // /// The decorator type used to decorate the . - // public void Decorate(Type serviceType, Type decoratorType) - // { - // _current.Decorate(serviceType, decoratorType); - // } - - // /// - // /// Decorates the with the given . - // /// - // /// The target service type. - // /// The decorator type used to decorate the . - // public void Decorate() where TDecorator : TService - // { - // _current.Decorate(); - // } - - // /// - // /// Decorates the using the given decorator . - // /// - // /// The target service type. - // /// A factory delegate used to create a decorator instance. - // public void Decorate(Expression> factory) - // { - // _current.Decorate(factory); - // } - - // /// - // /// Registers a decorator based on a instance. - // /// - // /// The instance that contains the decorator metadata. - // public void Decorate(DecoratorRegistration decoratorRegistration) - // { - // _current.Decorate(decoratorRegistration); - // } - - // /// - // /// Allows a registered service to be overridden by another . - // /// - // /// A function delegate that is used to determine the service that should be - // /// overridden using the returned from the . - // /// The factory delegate used to create a that overrides - // /// the incoming . - // public void Override(Func serviceSelector, Func serviceRegistrationFactory) - // { - // _current.Override(serviceSelector, serviceRegistrationFactory); - // } - - // /// - // /// Starts a new . - // /// - // /// - // public Scope BeginScope() - // { - // return _current.BeginScope(); - // } - - // /// - // /// Ends the current . - // /// - // public void EndCurrentScope() - // { - // _current.EndCurrentScope(); - // } - - // /// - // /// Gets an instance of the given . - // /// - // /// The type of the requested service. - // /// The requested service instance. - // public object GetInstance(Type serviceType) - // { - // var instance = _current.TryGetInstance(serviceType); - // return instance ?? _parent.GetInstance(serviceType); - // } - - // /// - // /// Gets an instance of the given . - // /// - // /// The type of the requested service. - // /// The arguments to be passed to the target instance. - // /// The requested service instance. - // public object GetInstance(Type serviceType, object[] arguments) - // { - // try - // { - // return _current.GetInstance(serviceType, arguments); - // } - // catch (InvalidOperationException) - // { - // return _parent.GetInstance(serviceType, arguments); - // } - // } - - // /// - // /// Gets an instance of the given . - // /// - // /// The type of the requested service. - // /// The name of the requested service. - // /// The arguments to be passed to the target instance. - // /// The requested service instance. - // public object GetInstance(Type serviceType, string serviceName, object[] arguments) - // { - // try - // { - // return _current.GetInstance(serviceType, serviceName, arguments); - // } - // catch (InvalidOperationException) - // { - // return _parent.GetInstance(serviceType, serviceName, arguments); - // } - // } - - // /// - // /// Gets a named instance of the given . - // /// - // /// The type of the requested service. - // /// The name of the requested service. - // /// The requested service instance. - // public object GetInstance(Type serviceType, string serviceName) - // { - // var instance = _current.TryGetInstance(serviceType, serviceName); - // return instance ?? _parent.GetInstance(serviceType, serviceName); - // } - - // /// - // /// Gets an instance of the given type. - // /// - // /// The type of the requested service. - // /// The requested service instance. - // public TService GetInstance() - // { - // var instance = _current.TryGetInstance() as object; - // return (TService) (instance ?? _parent.GetInstance()); - // } - - // /// - // /// Gets a named instance of the given . - // /// - // /// The type of the requested service. - // /// The name of the requested service. - // /// The requested service instance. - // public TService GetInstance(string serviceName) - // { - // var instance = _current.TryGetInstance(serviceName) as object; - // return (TService)(instance ?? _parent.GetInstance(serviceName)); - // } - - // /// - // /// Gets an instance of the given . - // /// - // /// The type of the argument. - // /// The type of the requested service. - // /// The argument value. - // /// The requested service instance. - // public TService GetInstance(T value) - // { - // try - // { - // return _current.GetInstance(value); - // } - // catch (InvalidOperationException) - // { - // return _parent.GetInstance(value); - // } - // } - - // /// - // /// Gets an instance of the given . - // /// - // /// The type of the parameter. - // /// The type of the requested service. - // /// The argument value. - // /// The name of the requested service. - // /// The requested service instance. - // public TService GetInstance(T value, string serviceName) - // { - // try - // { - // return _current.GetInstance(value, serviceName); - // } - // catch (InvalidOperationException) - // { - // return _parent.GetInstance(value, serviceName); - // } - // } - - // /// - // /// Gets an instance of the given . - // /// - // /// The type of the first parameter. - // /// The type of the second parameter. - // /// The type of the requested service. - // /// The first argument value. - // /// The second argument value. - // /// The requested service instance. - // public TService GetInstance(T1 arg1, T2 arg2) - // { - // try - // { - // return _current.GetInstance(arg1, arg2); - // } - // catch (InvalidOperationException) - // { - // return _parent.GetInstance(arg1, arg2); - // } - // } - - // /// - // /// Gets an instance of the given . - // /// - // /// The type of the first parameter. - // /// The type of the second parameter. - // /// The type of the requested service. - // /// The first argument value. - // /// The second argument value. - // /// The name of the requested service. - // /// The requested service instance. - // public TService GetInstance(T1 arg1, T2 arg2, string serviceName) - // { - // try - // { - // return _current.GetInstance(arg1, arg2, serviceName); - // } - // catch (InvalidOperationException) - // { - // return _parent.GetInstance(arg1, arg2, serviceName); - // } - // } - - // /// - // /// Gets an instance of the given . - // /// - // /// The type of the first parameter. - // /// The type of the second parameter. - // /// The type of the third parameter. - // /// The type of the requested service. - // /// The first argument value. - // /// The second argument value. - // /// The third argument value. - // /// The requested service instance. - // public TService GetInstance(T1 arg1, T2 arg2, T3 arg3) - // { - // try - // { - // return _current.GetInstance(arg1, arg2, arg3); - // } - // catch (InvalidOperationException) - // { - // return _parent.GetInstance(arg1, arg2, arg3); - // } - // } - - // /// - // /// Gets an instance of the given . - // /// - // /// The type of the first parameter. - // /// The type of the second parameter. - // /// The type of the third parameter. - // /// The type of the requested service. - // /// The first argument value. - // /// The second argument value. - // /// The third argument value. - // /// The name of the requested service. - // /// The requested service instance. - // public TService GetInstance(T1 arg1, T2 arg2, T3 arg3, string serviceName) - // { - // try - // { - // return _current.GetInstance(arg1, arg2, arg3, serviceName); - // } - // catch (InvalidOperationException) - // { - // return _parent.GetInstance(arg1, arg2, arg3, serviceName); - // } - // } - - // /// - // /// Gets an instance of the given . - // /// - // /// The type of the first parameter. - // /// The type of the second parameter. - // /// The type of the third parameter. - // /// The type of the fourth parameter. - // /// The type of the requested service. - // /// The first argument value. - // /// The second argument value. - // /// The third argument value. - // /// The fourth argument value. - // /// The requested service instance. - // public TService GetInstance(T1 arg1, T2 arg2, T3 arg3, T4 arg4) - // { - // try - // { - // return _current.GetInstance(arg1, arg2, arg3, arg4); - // } - // catch (InvalidOperationException) - // { - // return _parent.GetInstance(arg1, arg2, arg3, arg4); - // } - // } - - // /// - // /// Gets an instance of the given . - // /// - // /// The type of the first parameter. - // /// The type of the second parameter. - // /// The type of the third parameter. - // /// The type of the fourth parameter. - // /// The type of the requested service. - // /// The first argument value. - // /// The second argument value. - // /// The third argument value. - // /// The fourth argument value. - // /// The name of the requested service. - // /// The requested service instance. - // public TService GetInstance(T1 arg1, T2 arg2, T3 arg3, T4 arg4, string serviceName) - // { - // try - // { - // return _current.GetInstance(arg1, arg2, arg3, arg4, serviceName); - // } - // catch (InvalidOperationException) - // { - // return _parent.GetInstance(arg1, arg2, arg3, arg4, serviceName); - // } - // } - - // /// - // /// Gets an instance of the given . - // /// - // /// The type of the requested service. - // /// The requested service instance if available, otherwise null. - // public object TryGetInstance(Type serviceType) - // { - // return _current.TryGetInstance(serviceType) ?? _parent.TryGetInstance(serviceType); - // } - - // /// - // /// Gets a named instance of the given . - // /// - // /// The type of the requested service. - // /// The name of the requested service. - // /// The requested service instance if available, otherwise null. - // public object TryGetInstance(Type serviceType, string serviceName) - // { - // return _current.TryGetInstance(serviceType, serviceName) ?? _parent.TryGetInstance(serviceType, serviceName); - // } - - // /// - // /// Tries to get an instance of the given type. - // /// - // /// The type of the requested service. - // /// The requested service instance if available, otherwise default(T). - // public TService TryGetInstance() - // { - // return (TService) ((_current.TryGetInstance() as object) ?? _parent.TryGetInstance()); - // } - - // /// - // /// Tries to get an instance of the given type. - // /// - // /// The type of the requested service. - // /// The name of the requested service. - // /// The requested service instance if available, otherwise default(T). - // public TService TryGetInstance(string serviceName) - // { - // return (TService)((_current.TryGetInstance(serviceName) as object) ?? _parent.TryGetInstance(serviceName)); - // } - - // /// - // /// Gets all instances of the given . - // /// - // /// The type of services to resolve. - // /// A list that contains all implementations of the . - // public IEnumerable GetAllInstances(Type serviceType) - // { - // return _current.GetAllInstances(serviceType).Union(_parent.GetAllInstances(serviceType)); - // } - - // /// - // /// Gets all instances of type . - // /// - // /// The type of services to resolve. - // /// A list that contains all implementations of the type. - // public IEnumerable GetAllInstances() - // { - // return _current.GetAllInstances().Union(_parent.GetAllInstances()); - // } - - // /// - // /// Creates an instance of a concrete class. - // /// - // /// The type of class for which to create an instance. - // /// An instance of . - // /// The concrete type will be registered if not already registered with the container. - // public TService Create() where TService : class - // { - // return _current.Create(); - // } - - // /// - // /// Creates an instance of a concrete class. - // /// - // /// The type of class for which to create an instance. - // /// An instance of the . - // public object Create(Type serviceType) - // { - // return _current.Create(serviceType); - // } - - // /// - // /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources. - // /// - // public void Dispose() - // { - // //only dispose the current container - // _current.Dispose(); - // } - - // /// - // /// Gets or sets the that is responsible - // /// for providing the used to manage scopes. - // /// - // public IScopeManagerProvider ScopeManagerProvider - // { - // get { return _current.ScopeManagerProvider; } - // set { _current.ScopeManagerProvider = value; } - // } - - // /// - // /// Returns true if the container can create the requested service, otherwise false. - // /// - // /// The of the service. - // /// The name of the service. - // /// true if the container can create the requested service, otherwise false. - // public bool CanGetInstance(Type serviceType, string serviceName) - // { - // return _current.CanGetInstance(serviceType, serviceName) || _parent.CanGetInstance(serviceType, serviceName); - // } - - // /// - // /// Injects the property dependencies for a given . - // /// - // /// The target instance for which to inject its property dependencies. - // /// The with its property dependencies injected. - // public object InjectProperties(object instance) - // { - // var result = _current.InjectProperties(instance); - // return _parent.InjectProperties(result); - // } - //} - - } -} diff --git a/src/Umbraco.Core/LightInjectExtensions.cs b/src/Umbraco.Core/LightInjectExtensions.cs new file mode 100644 index 0000000000..8e938032ce --- /dev/null +++ b/src/Umbraco.Core/LightInjectExtensions.cs @@ -0,0 +1,88 @@ +using System; +using System.Collections.Generic; +using LightInject; + +namespace Umbraco.Core +{ + internal static class LightInjectExtensions + { + /// + /// In order for LightInject to deal with enumerables of the same type, each one needs to be named individually + /// + /// + /// + /// + /// + public static void RegisterCollection(this IServiceContainer container, IEnumerable implementationTypes) + where TLifetime : ILifetime + { + var i = 0; + foreach (var type in implementationTypes) + { + //This works as of 3.0.2.2: https://github.com/seesharper/LightInject/issues/68#issuecomment-70611055 + // but means that the explicit type is registered, not the implementing type + container.Register(type, Activator.CreateInstance()); + + //NOTE: This doesn't work, but it would be nice if it did (autofac supports thsi) + //container.Register(typeof(TService), type, + // Activator.CreateInstance()); + + //This does work, but requires a unique name per service + //container.Register(typeof(TService), type, + // //need to name it, we'll keep the name tiny + // i.ToString(CultureInfo.InvariantCulture), + // Activator.CreateInstance()); + //i++; + } + } + + /// + /// In order for LightInject to deal with enumerables of the same type, each one needs to be named individually + /// + /// + /// + /// + public static void RegisterCollection(this IServiceContainer container, IEnumerable implementationTypes) + { + var i = 0; + foreach (var type in implementationTypes) + { + //This works as of 3.0.2.2: https://github.com/seesharper/LightInject/issues/68#issuecomment-70611055 + // but means that the explicit type is registered, not the implementing type + container.Register(type); + + //NOTE: This doesn't work, but it would be nice if it did (autofac supports thsi) + //container.Register(typeof(TService), type); + + //This does work, but requires a unique name per service + //container.Register(typeof(TService), type, + // //need to name it, we'll keep the name tiny + // i.ToString(CultureInfo.InvariantCulture)); + //i++; + } + } + + /// + /// Creates a child container from the parent container + /// + /// + /// + public static ServiceContainer CreateChildContainer(this IServiceContainer parentContainer) + { + var child = new ChildContainer(parentContainer); + return child; + } + + private class ChildContainer : ServiceContainer + { + public ChildContainer(IServiceRegistry parentContainer) + { + foreach (var svc in parentContainer.AvailableServices) + { + Register(svc); + } + } + } + + } +} diff --git a/src/Umbraco.Core/Models/PublishedContent/PublishedContentModelFactoryResolver.cs b/src/Umbraco.Core/Models/PublishedContent/PublishedContentModelFactoryResolver.cs index 3e66fe0eeb..da649342cb 100644 --- a/src/Umbraco.Core/Models/PublishedContent/PublishedContentModelFactoryResolver.cs +++ b/src/Umbraco.Core/Models/PublishedContent/PublishedContentModelFactoryResolver.cs @@ -1,5 +1,5 @@ using System; -using Umbraco.Core.LightInject; +using LightInject; using Umbraco.Core.ObjectResolution; namespace Umbraco.Core.Models.PublishedContent diff --git a/src/Umbraco.Core/ObjectResolution/ContainerLazyManyObjectsResolver.cs b/src/Umbraco.Core/ObjectResolution/ContainerLazyManyObjectsResolver.cs index 81c826e4a5..a4382aa945 100644 --- a/src/Umbraco.Core/ObjectResolution/ContainerLazyManyObjectsResolver.cs +++ b/src/Umbraco.Core/ObjectResolution/ContainerLazyManyObjectsResolver.cs @@ -1,7 +1,7 @@ using System; using System.Collections.Generic; using System.Threading; -using Umbraco.Core.LightInject; +using LightInject; using Umbraco.Core.Logging; namespace Umbraco.Core.ObjectResolution diff --git a/src/Umbraco.Core/ObjectResolution/ContainerManyObjectsResolver.cs b/src/Umbraco.Core/ObjectResolution/ContainerManyObjectsResolver.cs index 13cfd27c2f..79ffa75ca5 100644 --- a/src/Umbraco.Core/ObjectResolution/ContainerManyObjectsResolver.cs +++ b/src/Umbraco.Core/ObjectResolution/ContainerManyObjectsResolver.cs @@ -2,7 +2,7 @@ using System; using System.Collections.Generic; using System.Linq; using System.Web; -using Umbraco.Core.LightInject; +using LightInject; using Umbraco.Core.Logging; using Umbraco.Core.Security; diff --git a/src/Umbraco.Core/ObjectResolution/ContainerSingleObjectResolver.cs b/src/Umbraco.Core/ObjectResolution/ContainerSingleObjectResolver.cs index dd5c7be7e3..5594c0c805 100644 --- a/src/Umbraco.Core/ObjectResolution/ContainerSingleObjectResolver.cs +++ b/src/Umbraco.Core/ObjectResolution/ContainerSingleObjectResolver.cs @@ -1,6 +1,6 @@ using System; using System.Linq.Expressions; -using Umbraco.Core.LightInject; +using LightInject; namespace Umbraco.Core.ObjectResolution { @@ -71,7 +71,7 @@ namespace Umbraco.Core.ObjectResolution /// /// /// - internal ContainerSingleObjectResolver(IServiceContainer container, Expression> implementationType) + internal ContainerSingleObjectResolver(IServiceContainer container, Func implementationType) { _container = container; _container.Register(implementationType, new PerContainerLifetime()); diff --git a/src/Umbraco.Core/ObjectResolution/ResolverBase.cs b/src/Umbraco.Core/ObjectResolution/ResolverBase.cs index 2f1653bd64..b0c4d21998 100644 --- a/src/Umbraco.Core/ObjectResolution/ResolverBase.cs +++ b/src/Umbraco.Core/ObjectResolution/ResolverBase.cs @@ -1,6 +1,6 @@ using System; using System.Threading; -using Umbraco.Core.LightInject; +using LightInject; namespace Umbraco.Core.ObjectResolution { diff --git a/src/Umbraco.Core/Persistence/Mappers/MappingResolver.cs b/src/Umbraco.Core/Persistence/Mappers/MappingResolver.cs index 67f771e8f5..a622bcda8c 100644 --- a/src/Umbraco.Core/Persistence/Mappers/MappingResolver.cs +++ b/src/Umbraco.Core/Persistence/Mappers/MappingResolver.cs @@ -2,7 +2,7 @@ using System.Collections.Concurrent; using System.Collections.Generic; using System.Linq; -using Umbraco.Core.LightInject; +using LightInject; using Umbraco.Core.Logging; using Umbraco.Core.ObjectResolution; diff --git a/src/Umbraco.Core/Persistence/Migrations/MigrationResolver.cs b/src/Umbraco.Core/Persistence/Migrations/MigrationResolver.cs index 96bd89648d..d9de233436 100644 --- a/src/Umbraco.Core/Persistence/Migrations/MigrationResolver.cs +++ b/src/Umbraco.Core/Persistence/Migrations/MigrationResolver.cs @@ -1,7 +1,7 @@ using System; using System.Collections.Generic; -using Umbraco.Core.LightInject; using System.Linq; +using LightInject; using Umbraco.Core.Logging; using Umbraco.Core.ObjectResolution; using Umbraco.Core.Persistence.SqlSyntax; diff --git a/src/Umbraco.Core/PropertyEditors/ParameterEditorResolver.cs b/src/Umbraco.Core/PropertyEditors/ParameterEditorResolver.cs index 14d62d0700..d6fe9f5b49 100644 --- a/src/Umbraco.Core/PropertyEditors/ParameterEditorResolver.cs +++ b/src/Umbraco.Core/PropertyEditors/ParameterEditorResolver.cs @@ -1,7 +1,7 @@ using System; using System.Collections.Generic; using System.Linq; -using Umbraco.Core.LightInject; +using LightInject; using Umbraco.Core.Logging; using Umbraco.Core.Manifest; using Umbraco.Core.ObjectResolution; diff --git a/src/Umbraco.Core/PropertyEditors/PropertyEditorResolver.cs b/src/Umbraco.Core/PropertyEditors/PropertyEditorResolver.cs index 6b3395ddf7..018d5fd762 100644 --- a/src/Umbraco.Core/PropertyEditors/PropertyEditorResolver.cs +++ b/src/Umbraco.Core/PropertyEditors/PropertyEditorResolver.cs @@ -2,7 +2,7 @@ using System.Collections.Generic; using System.IO; using System.Linq; -using Umbraco.Core.LightInject; +using LightInject; using Umbraco.Core.Cache; using Umbraco.Core.Logging; using Umbraco.Core.IO; diff --git a/src/Umbraco.Core/PropertyEditors/PropertyValueConvertersResolver.cs b/src/Umbraco.Core/PropertyEditors/PropertyValueConvertersResolver.cs index 5d15877b79..fa4501a268 100644 --- a/src/Umbraco.Core/PropertyEditors/PropertyValueConvertersResolver.cs +++ b/src/Umbraco.Core/PropertyEditors/PropertyValueConvertersResolver.cs @@ -2,7 +2,7 @@ using System; using System.Collections.Generic; using System.Linq; using System.Threading; -using Umbraco.Core.LightInject; +using LightInject; using Umbraco.Core.Logging; using Umbraco.Core.ObjectResolution; diff --git a/src/Umbraco.Core/Strings/ShortStringHelperResolver.cs b/src/Umbraco.Core/Strings/ShortStringHelperResolver.cs index 62e8957591..9a71a2eee9 100644 --- a/src/Umbraco.Core/Strings/ShortStringHelperResolver.cs +++ b/src/Umbraco.Core/Strings/ShortStringHelperResolver.cs @@ -1,6 +1,6 @@ using System; using System.Linq.Expressions; -using Umbraco.Core.LightInject; +using LightInject; using Umbraco.Core.ObjectResolution; namespace Umbraco.Core.Strings @@ -26,7 +26,7 @@ namespace Umbraco.Core.Strings /// /// /// - internal ShortStringHelperResolver(IServiceContainer container, Expression> implementationType) + internal ShortStringHelperResolver(IServiceContainer container, Func implementationType) : base(container, implementationType) { Resolution.Frozen += (sender, args) => Value.Freeze(); diff --git a/src/Umbraco.Core/Strings/UrlSegmentProviderResolver.cs b/src/Umbraco.Core/Strings/UrlSegmentProviderResolver.cs index 522d90605f..50e56a5f47 100644 --- a/src/Umbraco.Core/Strings/UrlSegmentProviderResolver.cs +++ b/src/Umbraco.Core/Strings/UrlSegmentProviderResolver.cs @@ -1,6 +1,6 @@ using System; using System.Collections.Generic; -using Umbraco.Core.LightInject; +using LightInject; using Umbraco.Core.Logging; using Umbraco.Core.ObjectResolution; diff --git a/src/Umbraco.Core/Sync/ServerMessengerResolver.cs b/src/Umbraco.Core/Sync/ServerMessengerResolver.cs index 884624856d..4571f92fec 100644 --- a/src/Umbraco.Core/Sync/ServerMessengerResolver.cs +++ b/src/Umbraco.Core/Sync/ServerMessengerResolver.cs @@ -1,6 +1,6 @@ using System; using System.Linq.Expressions; -using Umbraco.Core.LightInject; +using LightInject; using Umbraco.Core.ObjectResolution; namespace Umbraco.Core.Sync @@ -15,7 +15,7 @@ namespace Umbraco.Core.Sync { } - internal ServerMessengerResolver(IServiceContainer container, Expression> implementationType) + internal ServerMessengerResolver(IServiceContainer container, Func implementationType) : base(container, implementationType) { } diff --git a/src/Umbraco.Core/Sync/ServerRegistrarResolver.cs b/src/Umbraco.Core/Sync/ServerRegistrarResolver.cs index 5f94c2a632..f9637ff315 100644 --- a/src/Umbraco.Core/Sync/ServerRegistrarResolver.cs +++ b/src/Umbraco.Core/Sync/ServerRegistrarResolver.cs @@ -1,6 +1,6 @@ using System; using System.Linq.Expressions; -using Umbraco.Core.LightInject; +using LightInject; using Umbraco.Core.ObjectResolution; namespace Umbraco.Core.Sync @@ -23,7 +23,7 @@ namespace Umbraco.Core.Sync { } - internal ServerRegistrarResolver(IServiceContainer container, Expression> implementationType) + internal ServerRegistrarResolver(IServiceContainer container, Func implementationType) : base(container, implementationType) { } diff --git a/src/Umbraco.Core/Umbraco.Core.csproj b/src/Umbraco.Core/Umbraco.Core.csproj index 363a320efd..0408f3b09d 100644 --- a/src/Umbraco.Core/Umbraco.Core.csproj +++ b/src/Umbraco.Core/Umbraco.Core.csproj @@ -52,6 +52,10 @@ ..\packages\SharpZipLib.0.86.0\lib\20\ICSharpCode.SharpZipLib.dll + + ..\packages\LightInject.4.0.2\lib\net45\LightInject.dll + True + False ..\packages\log4net-mediumtrust.2.0.0\lib\log4net.dll @@ -330,8 +334,7 @@ - - + diff --git a/src/Umbraco.Core/UmbracoApplicationBase.cs b/src/Umbraco.Core/UmbracoApplicationBase.cs index 2fe8e106a3..04bae95290 100644 --- a/src/Umbraco.Core/UmbracoApplicationBase.cs +++ b/src/Umbraco.Core/UmbracoApplicationBase.cs @@ -5,8 +5,8 @@ using System.Reflection; using System.Threading; using System.Web; using System.Web.Hosting; -using Umbraco.Core.LightInject; using log4net; +using LightInject; using Umbraco.Core.Logging; using Umbraco.Core.ObjectResolution; using Umbraco.Core.Logging; diff --git a/src/Umbraco.Core/packages.config b/src/Umbraco.Core/packages.config index ce813b30c2..939b516ebf 100644 --- a/src/Umbraco.Core/packages.config +++ b/src/Umbraco.Core/packages.config @@ -2,8 +2,8 @@ + - diff --git a/src/Umbraco.Tests/Cache/DistributedCache/DistributedCacheTests.cs b/src/Umbraco.Tests/Cache/DistributedCache/DistributedCacheTests.cs index 0a9abbd837..85181882b5 100644 --- a/src/Umbraco.Tests/Cache/DistributedCache/DistributedCacheTests.cs +++ b/src/Umbraco.Tests/Cache/DistributedCache/DistributedCacheTests.cs @@ -1,11 +1,11 @@ using System; using System.Collections.Generic; using System.Linq; +using LightInject; using Moq; using NUnit.Framework; using umbraco.interfaces; using Umbraco.Core; -using Umbraco.Core.LightInject; using Umbraco.Core.Logging; using Umbraco.Core.ObjectResolution; using Umbraco.Core.Sync; diff --git a/src/Umbraco.Tests/Cache/PublishedCache/PublishedMediaCacheTests.cs b/src/Umbraco.Tests/Cache/PublishedCache/PublishedMediaCacheTests.cs index 002aedbf7d..c2b4934de9 100644 --- a/src/Umbraco.Tests/Cache/PublishedCache/PublishedMediaCacheTests.cs +++ b/src/Umbraco.Tests/Cache/PublishedCache/PublishedMediaCacheTests.cs @@ -4,11 +4,11 @@ using System.Collections.Generic; using System.Linq; using System.Xml; using Examine; +using LightInject; using Moq; using NUnit.Framework; using umbraco.BusinessLogic; using Umbraco.Core; -using Umbraco.Core.LightInject; using Umbraco.Core.Logging; using Umbraco.Core.Models; using Umbraco.Core.Models.PublishedContent; diff --git a/src/Umbraco.Tests/LibraryTests.cs b/src/Umbraco.Tests/LibraryTests.cs index 03deca8118..2039192d7d 100644 --- a/src/Umbraco.Tests/LibraryTests.cs +++ b/src/Umbraco.Tests/LibraryTests.cs @@ -16,7 +16,6 @@ using Umbraco.Web; using Umbraco.Web.PublishedCache; using Umbraco.Web.PublishedCache.XmlPublishedCache; using umbraco; -using Umbraco.Core.LightInject; namespace Umbraco.Tests { diff --git a/src/Umbraco.Tests/Migrations/FindingMigrationsTest.cs b/src/Umbraco.Tests/Migrations/FindingMigrationsTest.cs index eaff7f31a2..94e12fb2be 100644 --- a/src/Umbraco.Tests/Migrations/FindingMigrationsTest.cs +++ b/src/Umbraco.Tests/Migrations/FindingMigrationsTest.cs @@ -1,10 +1,10 @@ using System; using System.Collections.Generic; using System.Linq; +using LightInject; using Moq; using NUnit.Framework; using Umbraco.Core; -using Umbraco.Core.LightInject; using Umbraco.Core.Logging; using Umbraco.Core.ObjectResolution; using Umbraco.Core.Persistence; diff --git a/src/Umbraco.Tests/Migrations/TargetVersionSixthMigrationsTest.cs b/src/Umbraco.Tests/Migrations/TargetVersionSixthMigrationsTest.cs index ebde3f01be..8ed3ea6535 100644 --- a/src/Umbraco.Tests/Migrations/TargetVersionSixthMigrationsTest.cs +++ b/src/Umbraco.Tests/Migrations/TargetVersionSixthMigrationsTest.cs @@ -8,7 +8,6 @@ using NUnit.Framework; using Semver; using SQLCE4Umbraco; using Umbraco.Core; -using Umbraco.Core.LightInject; using Umbraco.Core.Logging; using Umbraco.Core.ObjectResolution; using Umbraco.Core.Persistence; diff --git a/src/Umbraco.Tests/Migrations/Upgrades/BaseUpgradeTest.cs b/src/Umbraco.Tests/Migrations/Upgrades/BaseUpgradeTest.cs index 9a549e9e51..8faa4f8717 100644 --- a/src/Umbraco.Tests/Migrations/Upgrades/BaseUpgradeTest.cs +++ b/src/Umbraco.Tests/Migrations/Upgrades/BaseUpgradeTest.cs @@ -6,7 +6,6 @@ using NUnit.Framework; using Semver; using Umbraco.Core; using Umbraco.Core.Configuration; -using Umbraco.Core.LightInject; using Umbraco.Core.Logging; using Umbraco.Core.ObjectResolution; using Umbraco.Core.Persistence; diff --git a/src/Umbraco.Tests/PublishedContent/PublishedContentMoreTests.cs b/src/Umbraco.Tests/PublishedContent/PublishedContentMoreTests.cs index 85a9f27e3a..c79da17251 100644 --- a/src/Umbraco.Tests/PublishedContent/PublishedContentMoreTests.cs +++ b/src/Umbraco.Tests/PublishedContent/PublishedContentMoreTests.cs @@ -11,7 +11,6 @@ using Umbraco.Core.PropertyEditors; using Umbraco.Web; using Umbraco.Tests.TestHelpers; using umbraco.BusinessLogic; -using Umbraco.Core.LightInject; using Umbraco.Web.PublishedCache.XmlPublishedCache; using Umbraco.Web.Security; diff --git a/src/Umbraco.Tests/PublishedContent/PublishedContentTestBase.cs b/src/Umbraco.Tests/PublishedContent/PublishedContentTestBase.cs index b819f9252f..dd7c1d80ac 100644 --- a/src/Umbraco.Tests/PublishedContent/PublishedContentTestBase.cs +++ b/src/Umbraco.Tests/PublishedContent/PublishedContentTestBase.cs @@ -3,7 +3,6 @@ using System.IO; using System.Linq; using Umbraco.Core; using Umbraco.Core.Configuration; -using Umbraco.Core.LightInject; using Umbraco.Core.Models; using Umbraco.Core.Models.PublishedContent; using Umbraco.Core.PropertyEditors; diff --git a/src/Umbraco.Tests/PublishedContent/PublishedMediaTests.cs b/src/Umbraco.Tests/PublishedContent/PublishedMediaTests.cs index f0991fa2ab..379832518a 100644 --- a/src/Umbraco.Tests/PublishedContent/PublishedMediaTests.cs +++ b/src/Umbraco.Tests/PublishedContent/PublishedMediaTests.cs @@ -27,7 +27,7 @@ using UmbracoExamine; using UmbracoExamine.DataServices; using umbraco.BusinessLogic; using System.Linq; -using Umbraco.Core.LightInject; +using LightInject; using Umbraco.Core.Logging; using Umbraco.Core.Strings; diff --git a/src/Umbraco.Tests/TestHelpers/BaseUmbracoApplicationTest.cs b/src/Umbraco.Tests/TestHelpers/BaseUmbracoApplicationTest.cs index dfab4bf4ed..4fae7a0564 100644 --- a/src/Umbraco.Tests/TestHelpers/BaseUmbracoApplicationTest.cs +++ b/src/Umbraco.Tests/TestHelpers/BaseUmbracoApplicationTest.cs @@ -5,13 +5,13 @@ using System.IO; using System.Linq; using System.Reflection; using AutoMapper; +using LightInject; using Moq; using NUnit.Framework; using Umbraco.Core; using Umbraco.Core.Cache; using Umbraco.Core.Configuration.UmbracoSettings; using Umbraco.Core.IO; -using Umbraco.Core.LightInject; using Umbraco.Core.Logging; using Umbraco.Core.Models.Mapping; using Umbraco.Core.ObjectResolution; diff --git a/src/Umbraco.Tests/TestHelpers/BaseUsingSqlCeSyntax.cs b/src/Umbraco.Tests/TestHelpers/BaseUsingSqlCeSyntax.cs index 039d7962aa..b31483484d 100644 --- a/src/Umbraco.Tests/TestHelpers/BaseUsingSqlCeSyntax.cs +++ b/src/Umbraco.Tests/TestHelpers/BaseUsingSqlCeSyntax.cs @@ -1,8 +1,8 @@ -using Moq; +using LightInject; +using Moq; using NUnit.Framework; using Umbraco.Core; using Umbraco.Core.Cache; -using Umbraco.Core.LightInject; using Umbraco.Core.Logging; using Umbraco.Core.ObjectResolution; using Umbraco.Core.Persistence.Mappers; diff --git a/src/Umbraco.Tests/Umbraco.Tests.csproj b/src/Umbraco.Tests/Umbraco.Tests.csproj index 6650944068..9916d8ec57 100644 --- a/src/Umbraco.Tests/Umbraco.Tests.csproj +++ b/src/Umbraco.Tests/Umbraco.Tests.csproj @@ -67,6 +67,10 @@ False ..\packages\SharpZipLib.0.86.0\lib\20\ICSharpCode.SharpZipLib.dll + + ..\packages\LightInject.4.0.2\lib\net45\LightInject.dll + True + False ..\packages\log4net-mediumtrust.2.0.0\lib\log4net.dll diff --git a/src/Umbraco.Tests/packages.config b/src/Umbraco.Tests/packages.config index 8986f13197..90623bff26 100644 --- a/src/Umbraco.Tests/packages.config +++ b/src/Umbraco.Tests/packages.config @@ -3,6 +3,7 @@ + diff --git a/src/Umbraco.Web/LightInject/Mvc/LightInject.Mvc.cs b/src/Umbraco.Web/LightInject/Mvc/LightInject.Mvc.cs deleted file mode 100644 index e949b40d1e..0000000000 --- a/src/Umbraco.Web/LightInject/Mvc/LightInject.Mvc.cs +++ /dev/null @@ -1,203 +0,0 @@ -/***************************************************************************** - The MIT License (MIT) - - Copyright (c) 2014 bernhard.richter@gmail.com - - Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated documentation files (the "Software"), to deal - in the Software without restriction, including without limitation the rights - to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - copies of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included in all - copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - SOFTWARE. -****************************************************************************** - LightInject.Mvc version 1.0.0.4 - http://seesharper.github.io/LightInject/ - http://twitter.com/bernhardrichter -******************************************************************************/ - -using Umbraco.Core.LightInject; - -[module: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.ReadabilityRules", "SA1126:PrefixCallsCorrectly", Justification = "Reviewed")] -[module: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.ReadabilityRules", "SA1101:PrefixLocalCallsWithThis", Justification = "No inheritance")] -[module: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.MaintainabilityRules", "SA1402:FileMayOnlyContainASingleClass", Justification = "Single source file deployment.")] -[module: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.MaintainabilityRules", "SA1403:FileMayOnlyContainASingleNamespace", Justification = "Extension methods must be visible")] -[module: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.DocumentationRules", "SA1633:FileMustHaveHeader", Justification = "Custom header.")] -[module: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.DocumentationRules", "SA1600:ElementsMustBeDocumented", Justification = "All public members are documented.")] - -namespace Umbraco.Web.LightInject -{ - using System.Linq; - using System.Reflection; - using System.Web.Mvc; - using LightInject.Mvc; - - /// - /// Extends the interface with a method that - /// enables dependency injection in an ASP.NET MVC application. - /// - [System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage] - internal static class MvcContainerExtensions - { - /// - /// Registers all implementations found in the given . - /// - /// The target . - /// A list of assemblies from which to register implementations. - public static void RegisterControllers(this IServiceRegistry serviceRegistry, params Assembly[] assemblies) - { - foreach (var assembly in assemblies) - { - var controllerTypes = - assembly.GetTypes().Where(t => !t.IsAbstract && typeof(IController).IsAssignableFrom(t)); - foreach (var controllerType in controllerTypes) - { - serviceRegistry.Register(controllerType, new PerRequestLifeTime()); - } - } - } - - /// - /// Registers all implementations found in this assembly. - /// - /// The target . - public static void RegisterControllers(this IServiceRegistry serviceRegistry) - { - RegisterControllers(serviceRegistry, Assembly.GetCallingAssembly()); - } - - /// - /// Enables dependency injection in an ASP.NET MVC application. - /// - /// The target . - public static void EnableMvc(this IServiceContainer serviceContainer) - { - ((ServiceContainer)serviceContainer).EnablePerWebRequestScope(); - SetDependencyResolver(serviceContainer); - InitializeFilterAttributeProvider(serviceContainer); - } - - private static void SetDependencyResolver(IServiceContainer serviceContainer) - { - DependencyResolver.SetResolver(new LightInjectMvcDependencyResolver(serviceContainer)); - } - - private static void InitializeFilterAttributeProvider(IServiceContainer serviceContainer) - { - RemoveExistingFilterAttributeFilterProviders(); - var filterProvider = new LightInjectFilterProvider(serviceContainer); - FilterProviders.Providers.Add(filterProvider); - } - - private static void RemoveExistingFilterAttributeFilterProviders() - { - var existingFilterAttributeProviders = - FilterProviders.Providers.OfType().ToArray(); - foreach (FilterAttributeFilterProvider filterAttributeFilterProvider in existingFilterAttributeProviders) - { - FilterProviders.Providers.Remove(filterAttributeFilterProvider); - } - } - } -} - -namespace Umbraco.Web.LightInject.Mvc -{ - using System; - using System.Collections.Generic; - using System.Linq; - using System.Web.Mvc; - - /// - /// An adapter for the LightInject service container. - /// - [System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage] - internal class LightInjectMvcDependencyResolver : IDependencyResolver - { - private readonly IServiceContainer serviceContainer; - - /// - /// Initializes a new instance of the class. - /// - /// The instance to - /// be used for resolving service instances. - internal LightInjectMvcDependencyResolver(IServiceContainer serviceContainer) - { - this.serviceContainer = serviceContainer; - } - - /// - /// Resolves singly registered services that support arbitrary object creation. - /// - /// - /// The requested service or object. - /// - /// The type of the requested service or object. - public object GetService(Type serviceType) - { - return serviceContainer.TryGetInstance(serviceType); - } - - /// - /// Resolves multiply registered services. - /// - /// - /// The requested services. - /// - /// The type of the requested services. - public IEnumerable GetServices(Type serviceType) - { - return serviceContainer.GetAllInstances(serviceType); - } - } - - /// - /// A that uses an - /// to inject property dependencies into instances. - /// - [System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage] - internal class LightInjectFilterProvider : FilterAttributeFilterProvider - { - private readonly IServiceContainer serviceContainer; - - /// - /// Initializes a new instance of the class. - /// - /// The instance - /// used to inject property dependencies. - public LightInjectFilterProvider(IServiceContainer serviceContainer) - { - this.serviceContainer = serviceContainer; - serviceContainer.RegisterInstance(this); - } - - /// - /// Aggregates the filters from all of the filter providers into one collection. - /// - /// - /// The collection filters from all of the filter providers. - /// - /// The controller context. - /// The action descriptor. - public override IEnumerable GetFilters(ControllerContext controllerContext, ActionDescriptor actionDescriptor) - { - var filters = base.GetFilters(controllerContext, actionDescriptor).ToArray(); - foreach (var filter in filters) - { - serviceContainer.InjectProperties(filter.Instance); - } - - return filters; - } - } -} \ No newline at end of file diff --git a/src/Umbraco.Web/LightInject/Web/LightInject.Web.cs b/src/Umbraco.Web/LightInject/Web/LightInject.Web.cs deleted file mode 100644 index c3c06b6003..0000000000 --- a/src/Umbraco.Web/LightInject/Web/LightInject.Web.cs +++ /dev/null @@ -1,164 +0,0 @@ -/***************************************************************************** - The MIT License (MIT) - - Copyright (c) 2014 bernhard.richter@gmail.com - - Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated documentation files (the "Software"), to deal - in the Software without restriction, including without limitation the rights - to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - copies of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included in all - copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - SOFTWARE. -****************************************************************************** - LightInject.Web version 1.0.0.7 - http://seesharper.github.io/LightInject/ - http://twitter.com/bernhardrichter -******************************************************************************/ - -using Umbraco.Core.LightInject; - -[assembly: System.Web.PreApplicationStartMethod(typeof(Umbraco.Web.LightInject.Web.LightInjectHttpModuleInitializer), "Initialize")] -[module: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.ReadabilityRules", "SA1126:PrefixCallsCorrectly", Justification = "Reviewed")] -[module: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.ReadabilityRules", "SA1101:PrefixLocalCallsWithThis", Justification = "No inheritance")] -[module: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.MaintainabilityRules", "SA1402:FileMayOnlyContainASingleClass", Justification = "Single source file deployment.")] -[module: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.MaintainabilityRules", "SA1403:FileMayOnlyContainASingleNamespace", Justification = "Extension methods must be visible")] -[module: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.DocumentationRules", "SA1633:FileMustHaveHeader", Justification = "Custom header.")] -[module: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.DocumentationRules", "SA1600:ElementsMustBeDocumented", Justification = "All public members are documented.")] - -namespace Umbraco.Web.LightInject -{ - using Web; - - /// - /// Extends the interface with a method - /// to enable services that are scoped per web request. - /// - [System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage] - internal static class WebContainerExtensions - { - /// - /// Ensures that services registered with the is properly - /// disposed when the web request ends. - /// - /// The target . - public static void EnablePerWebRequestScope(this ServiceContainer serviceContainer) - { - serviceContainer.ScopeManagerProvider = new PerWebRequestScopeManagerProvider(); - } - } -} - -namespace Umbraco.Web.LightInject.Web -{ - using System; - using System.Web; - using Microsoft.Web.Infrastructure.DynamicModuleHelper; - - /// - /// Registers the with the current . - /// - public static class LightInjectHttpModuleInitializer - { - private static bool isInitialized; - - /// - /// Executed before the is started and registers - /// the with the current . - /// - public static void Initialize() - { - if (!isInitialized) - { - isInitialized = true; - DynamicModuleUtility.RegisterModule(typeof(LightInjectHttpModule)); - } - } - } - - /// - /// A that ensures that services registered - /// with the lifetime is scoped per web request. - /// - [System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage] - public class LightInjectHttpModule : IHttpModule - { - /// - /// Initializes a module and prepares it to handle requests. - /// - /// An that provides access to the methods, properties, and events common to all application objects within an ASP.NET application - public void Init(HttpApplication context) - { - context.BeginRequest += BeginRequest; - context.EndRequest += EndRequest; - } - - /// - /// Disposes of the resources (other than memory) used by the module that implements . - /// - public void Dispose() - { - } - - private static void EndRequest(object sender, EventArgs eventArgs) - { - var application = sender as HttpApplication; - if (application == null) - { - return; - } - - var scopeManager = (ScopeManager)application.Context.Items["ScopeManager"]; - if (scopeManager != null) - { - scopeManager.CurrentScope.Dispose(); - } - } - - private static void BeginRequest(object sender, EventArgs eventArgs) - { - var application = sender as HttpApplication; - if (application == null) - { - return; - } - - var scopeManager = new ScopeManager(); - scopeManager.BeginScope(); - application.Context.Items["ScopeManager"] = scopeManager; - } - } - - /// - /// An that provides the - /// used by the current . - /// - [System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage] - internal class PerWebRequestScopeManagerProvider : IScopeManagerProvider - { - /// - /// Returns the that is responsible for managing scopes. - /// - /// The that is responsible for managing scopes. - public ScopeManager GetScopeManager() - { - var scopeManager = (ScopeManager)HttpContext.Current.Items["ScopeManager"]; - if (scopeManager == null) - { - throw new InvalidOperationException("Unable to locate a scope manager for the current HttpRequest. Ensure that the LightInjectHttpModule has been added."); - } - - return scopeManager; - } - } -} \ No newline at end of file diff --git a/src/Umbraco.Web/LightInject/WebApi/LightInject.WebApi.cs b/src/Umbraco.Web/LightInject/WebApi/LightInject.WebApi.cs deleted file mode 100644 index fba4464d17..0000000000 --- a/src/Umbraco.Web/LightInject/WebApi/LightInject.WebApi.cs +++ /dev/null @@ -1,235 +0,0 @@ -/***************************************************************************** - The MIT License (MIT) - - Copyright (c) 2014 bernhard.richter@gmail.com - - Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated documentation files (the "Software"), to deal - in the Software without restriction, including without limitation the rights - to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - copies of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included in all - copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - SOFTWARE. -****************************************************************************** - LightInject.WebApi version 1.0.0.3 - http://www.lightinject.net/ - http://twitter.com/bernhardrichter -******************************************************************************/ - -using Umbraco.Core.LightInject; - -[module: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.ReadabilityRules", "SA1126:PrefixCallsCorrectly", Justification = "Reviewed")] -[module: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.ReadabilityRules", "SA1101:PrefixLocalCallsWithThis", Justification = "No inheritance")] -[module: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.MaintainabilityRules", "SA1402:FileMayOnlyContainASingleClass", Justification = "Single source file deployment.")] -[module: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.MaintainabilityRules", "SA1403:FileMayOnlyContainASingleNamespace", Justification = "Extension methods must be visible")] -[module: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.DocumentationRules", "SA1633:FileMustHaveHeader", Justification = "Custom header.")] -[module: System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.DocumentationRules", "SA1600:ElementsMustBeDocumented", Justification = "All public members are documented.")] - -namespace Umbraco.Web.LightInject -{ - using System.Linq; - using System.Reflection; - using System.Web.Http; - using System.Web.Http.Controllers; - using System.Web.Http.Filters; - using LightInject.WebApi; - - /// - /// Extends the interface with methods that - /// enables dependency injection in a Web API application. - /// - [System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage] - internal static class WebApiContainerExtensions - { - /// - /// Enables dependency injection in a Web API application. - /// - /// The target . - /// The that represents the configuration of this Web API application. - public static void EnableWebApi(this IServiceContainer serviceContainer, HttpConfiguration httpConfiguration) - { - httpConfiguration.DependencyResolver = new LightInjectWebApiDependencyResolver(serviceContainer); - var provider = httpConfiguration.Services.GetFilterProviders(); - httpConfiguration.Services.RemoveAll(typeof(IFilterProvider), o => true); - httpConfiguration.Services.Add(typeof(IFilterProvider), new LightInjectWebApiFilterProvider(serviceContainer, provider)); - } - - /// - /// Registers all implementations found in the given . - /// - /// The target . - /// A list of assemblies from which to register implementations. - public static void RegisterApiControllers(this IServiceRegistry serviceRegistry, params Assembly[] assemblies) - { - foreach (var assembly in assemblies) - { - var controllerTypes = assembly.GetTypes().Where(t => !t.IsAbstract && typeof(IHttpController).IsAssignableFrom(t)); - foreach (var controllerType in controllerTypes) - { - serviceRegistry.Register(controllerType, new PerRequestLifeTime()); - } - } - } - - /// - /// Registers all implementations found in this assembly. - /// - /// The target . - public static void RegisterApiControllers(this IServiceRegistry serviceRegistry) - { - RegisterApiControllers(serviceRegistry, Assembly.GetCallingAssembly()); - } - } -} - -namespace Umbraco.Web.LightInject.WebApi -{ - using System; - using System.Collections.Generic; - using System.Linq; - using System.Web.Http; - using System.Web.Http.Controllers; - using System.Web.Http.Dependencies; - using System.Web.Http.Filters; - - /// - /// An adapter for the LightInject service container - /// that enables instances and their dependencies to be - /// resolved through the service container. - /// - [System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage] - internal class LightInjectWebApiDependencyResolver : IDependencyResolver - { - private readonly IServiceContainer serviceContainer; - - /// - /// Initializes a new instance of the class. - /// - /// The instance to - /// be used for resolving service instances. - internal LightInjectWebApiDependencyResolver(IServiceContainer serviceContainer) - { - this.serviceContainer = serviceContainer; - } - - /// - /// Disposes the underlying . - /// - public void Dispose() - { - serviceContainer.Dispose(); - } - - /// - /// Gets an instance of the given . - /// - /// The type of the requested service. - /// The requested service instance if available, otherwise null. - public object GetService(Type serviceType) - { - return serviceContainer.TryGetInstance(serviceType); - } - - /// - /// Gets all instance of the given . - /// - /// The type of services to resolve. - /// A list that contains all implementations of the . - public IEnumerable GetServices(Type serviceType) - { - return serviceContainer.GetAllInstances(serviceType); - } - - /// - /// Starts a new that represents - /// the scope for services registered with . - /// - /// - /// A new . - /// - public IDependencyScope BeginScope() - { - return new LightInjectWebApiDependencyScope(serviceContainer, serviceContainer.BeginScope()); - } - } - - [System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage] - internal class LightInjectWebApiDependencyScope : IDependencyScope - { - private readonly IServiceContainer serviceContainer; - private readonly Scope scope; - - public LightInjectWebApiDependencyScope(IServiceContainer serviceContainer, Scope scope) - { - this.serviceContainer = serviceContainer; - this.scope = scope; - } - - public object GetService(Type serviceType) - { - return serviceContainer.GetInstance(serviceType); - } - - public IEnumerable GetServices(Type serviceType) - { - return serviceContainer.GetAllInstances(serviceType); - } - - public void Dispose() - { - scope.Dispose(); - } - } - - /// - /// A that uses an - /// to inject property dependencies into instances. - /// - [System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage] - internal class LightInjectWebApiFilterProvider : IFilterProvider - { - private readonly IServiceContainer serviceContainer; - private readonly IEnumerable filterProviders; - - /// - /// Initializes a new instance of the class. - /// - /// The instance - /// used to inject property dependencies. - /// The list of existing filter providers. - public LightInjectWebApiFilterProvider(IServiceContainer serviceContainer, IEnumerable filterProviders) - { - this.serviceContainer = serviceContainer; - this.filterProviders = filterProviders; - } - - /// - /// Returns an enumeration of filters. - /// - /// - /// An enumeration of filters. - /// - /// The HTTP configuration.The action descriptor. - public IEnumerable GetFilters(HttpConfiguration configuration, HttpActionDescriptor actionDescriptor) - { - var filters = filterProviders.SelectMany(p => p.GetFilters(configuration, actionDescriptor)).ToArray(); - - foreach (var filterInfo in filters) - { - serviceContainer.InjectProperties(filterInfo.Instance); - } - - return filters; - } - } -} \ No newline at end of file diff --git a/src/Umbraco.Web/LightInject/LightInjectExtensions.cs b/src/Umbraco.Web/LightInjectExtensions.cs similarity index 87% rename from src/Umbraco.Web/LightInject/LightInjectExtensions.cs rename to src/Umbraco.Web/LightInjectExtensions.cs index 756e689608..50b42adec9 100644 --- a/src/Umbraco.Web/LightInject/LightInjectExtensions.cs +++ b/src/Umbraco.Web/LightInjectExtensions.cs @@ -1,15 +1,10 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Reflection; -using System.Text; -using System.Threading.Tasks; +using System.Reflection; using System.Web.Http.Controllers; using System.Web.Mvc; +using LightInject; using Umbraco.Core; -using Umbraco.Core.LightInject; -namespace Umbraco.Web.LightInject +namespace Umbraco.Web { internal static class LightInjectExtensions { diff --git a/src/Umbraco.Web/Media/ThumbnailProviders/ThumbnailProvidersResolver.cs b/src/Umbraco.Web/Media/ThumbnailProviders/ThumbnailProvidersResolver.cs index e0aa2569c1..f4e3874cb1 100644 --- a/src/Umbraco.Web/Media/ThumbnailProviders/ThumbnailProvidersResolver.cs +++ b/src/Umbraco.Web/Media/ThumbnailProviders/ThumbnailProvidersResolver.cs @@ -3,8 +3,8 @@ using System.Collections.Generic; using System.Linq; using System.Text; using System.Web; +using LightInject; using Umbraco.Core; -using Umbraco.Core.LightInject; using Umbraco.Core.Logging; using Umbraco.Core.Media; using Umbraco.Core.ObjectResolution; diff --git a/src/Umbraco.Web/PublishedCache/PublishedCachesResolver.cs b/src/Umbraco.Web/PublishedCache/PublishedCachesResolver.cs index 22e9ea2e65..f196e6a2d1 100644 --- a/src/Umbraco.Web/PublishedCache/PublishedCachesResolver.cs +++ b/src/Umbraco.Web/PublishedCache/PublishedCachesResolver.cs @@ -1,6 +1,6 @@ using System; using System.Linq.Expressions; -using Umbraco.Core.LightInject; +using LightInject; using Umbraco.Core.ObjectResolution; namespace Umbraco.Web.PublishedCache @@ -35,7 +35,7 @@ namespace Umbraco.Web.PublishedCache /// /// /// - public PublishedCachesResolver(IServiceContainer container, Expression> implementationType) : base(container, implementationType) + public PublishedCachesResolver(IServiceContainer container, Func implementationType) : base(container, implementationType) { } diff --git a/src/Umbraco.Web/Routing/ContentFinderResolver.cs b/src/Umbraco.Web/Routing/ContentFinderResolver.cs index e629566dbd..22b953bdea 100644 --- a/src/Umbraco.Web/Routing/ContentFinderResolver.cs +++ b/src/Umbraco.Web/Routing/ContentFinderResolver.cs @@ -1,6 +1,6 @@ using System; using System.Collections.Generic; -using Umbraco.Core.LightInject; +using LightInject; using Umbraco.Core.Logging; using Umbraco.Core.ObjectResolution; diff --git a/src/Umbraco.Web/Routing/ContentLastChanceFinderResolver.cs b/src/Umbraco.Web/Routing/ContentLastChanceFinderResolver.cs index 9d3e06ac6f..f4966f39e4 100644 --- a/src/Umbraco.Web/Routing/ContentLastChanceFinderResolver.cs +++ b/src/Umbraco.Web/Routing/ContentLastChanceFinderResolver.cs @@ -1,6 +1,6 @@ using System; using System.Linq.Expressions; -using Umbraco.Core.LightInject; +using LightInject; using Umbraco.Core.ObjectResolution; namespace Umbraco.Web.Routing @@ -43,7 +43,7 @@ namespace Umbraco.Web.Routing /// /// /// - internal ContentLastChanceFinderResolver(IServiceContainer container, Expression> implementationType) + internal ContentLastChanceFinderResolver(IServiceContainer container, Func implementationType) : base(container, implementationType) { } diff --git a/src/Umbraco.Web/Routing/SiteDomainHelperResolver.cs b/src/Umbraco.Web/Routing/SiteDomainHelperResolver.cs index 34fe2c7718..3ff9010268 100644 --- a/src/Umbraco.Web/Routing/SiteDomainHelperResolver.cs +++ b/src/Umbraco.Web/Routing/SiteDomainHelperResolver.cs @@ -1,6 +1,6 @@ using System; using System.Linq.Expressions; -using Umbraco.Core.LightInject; +using LightInject; using Umbraco.Core.ObjectResolution; namespace Umbraco.Web.Routing @@ -34,7 +34,7 @@ namespace Umbraco.Web.Routing /// /// /// - internal SiteDomainHelperResolver(IServiceContainer container, Expression> implementationType) + internal SiteDomainHelperResolver(IServiceContainer container, Func implementationType) : base(container, implementationType) { } diff --git a/src/Umbraco.Web/Routing/UrlProviderResolver.cs b/src/Umbraco.Web/Routing/UrlProviderResolver.cs index 035eee12a1..9000b40715 100644 --- a/src/Umbraco.Web/Routing/UrlProviderResolver.cs +++ b/src/Umbraco.Web/Routing/UrlProviderResolver.cs @@ -2,7 +2,7 @@ using System.Collections.Generic; using System.Linq; using System.Text; -using Umbraco.Core.LightInject; +using LightInject; using Umbraco.Core.Logging; using Umbraco.Core.ObjectResolution; diff --git a/src/Umbraco.Web/Umbraco.Web.csproj b/src/Umbraco.Web/Umbraco.Web.csproj index 70ca4c37c3..8eb32ef53c 100644 --- a/src/Umbraco.Web/Umbraco.Web.csproj +++ b/src/Umbraco.Web/Umbraco.Web.csproj @@ -128,6 +128,22 @@ False ..\packages\SharpZipLib.0.86.0\lib\20\ICSharpCode.SharpZipLib.dll + + ..\packages\LightInject.4.0.2\lib\net45\LightInject.dll + True + + + ..\packages\LightInject.Mvc.1.0.0.4\lib\net45\LightInject.Mvc.dll + True + + + ..\packages\LightInject.Web.1.0.0.4\lib\net45\LightInject.Web.dll + True + + + ..\packages\LightInject.WebApi.1.0.0.4\lib\net45\LightInject.WebApi.dll + True + False ..\packages\Lucene.Net.2.9.4.1\lib\net40\Lucene.Net.dll @@ -295,9 +311,7 @@ - - - + @@ -336,7 +350,6 @@ - diff --git a/src/Umbraco.Web/WebBootManager.cs b/src/Umbraco.Web/WebBootManager.cs index ec8c2c8c82..796b65c545 100644 --- a/src/Umbraco.Web/WebBootManager.cs +++ b/src/Umbraco.Web/WebBootManager.cs @@ -13,11 +13,11 @@ using System.Web.Routing; using ClientDependency.Core.Config; using Examine; using Examine.Config; +using LightInject; using umbraco; using Umbraco.Core; using Umbraco.Core.Configuration; using Umbraco.Core.Dictionary; -using Umbraco.Core.LightInject; using Umbraco.Core.Logging; using Umbraco.Core.Macros; using Umbraco.Core.ObjectResolution; @@ -27,7 +27,6 @@ using Umbraco.Core.PropertyEditors.ValueConverters; using Umbraco.Core.Sync; using Umbraco.Web.Dictionary; using Umbraco.Web.Install; -using Umbraco.Web.LightInject; using Umbraco.Web.Macros; using Umbraco.Web.Media; using Umbraco.Web.Media.ThumbnailProviders; @@ -50,7 +49,6 @@ using Umbraco.Core.Services; using GlobalSettings = Umbraco.Core.Configuration.GlobalSettings; using ProfilingViewEngine = Umbraco.Core.Profiling.ProfilingViewEngine; using TypeHelper = Umbraco.Core.TypeHelper; -using Umbraco.Core.LightInject; namespace Umbraco.Web @@ -316,7 +314,7 @@ namespace Umbraco.Web base.ConfigureServices(container); //IoC setup for LightInject for mvc/webapi - Container.EnableMvc(); + MvcContainerExtensions.EnableMvc(Container); Container.RegisterMvcControllers(PluginManager); container.EnablePerWebRequestScope(); container.EnableWebApi(GlobalConfiguration.Configuration); diff --git a/src/Umbraco.Web/app.config b/src/Umbraco.Web/app.config index 2b15194775..88dfbc0452 100644 --- a/src/Umbraco.Web/app.config +++ b/src/Umbraco.Web/app.config @@ -67,6 +67,10 @@ + + + + \ No newline at end of file diff --git a/src/Umbraco.Web/packages.config b/src/Umbraco.Web/packages.config index d33bbcd37a..48b6aa4cd0 100644 --- a/src/Umbraco.Web/packages.config +++ b/src/Umbraco.Web/packages.config @@ -5,9 +5,10 @@ - - - + + + +