// This software is part of the Autofac IoC container // Copyright © 2011 Autofac Contributors // http://autofac.org // // 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. using System; using System.Collections.Generic; using System.Web.Mvc; namespace Autofac.Integration.Mvc { /// /// Autofac implementation of the interface. /// public class AutofacDependencyResolver : IDependencyResolver { readonly ILifetimeScope _container; readonly Action _configurationAction; ILifetimeScopeProvider _lifetimeScopeProvider; /// /// Initializes a new instance of the class. /// /// The container that nested lifetime scopes will be create from. public AutofacDependencyResolver(ILifetimeScope container) { if (container == null) throw new ArgumentNullException("container"); _container = container; } /// /// Initializes a new instance of the class. /// /// The container that nested lifetime scopes will be create from. /// Action on a /// that adds component registations visible only in nested lifetime scopes. public AutofacDependencyResolver(ILifetimeScope container, Action configurationAction) : this(container) { if (configurationAction == null) throw new ArgumentNullException("configurationAction"); _configurationAction = configurationAction; } /// /// Initializes a new instance of the class. /// /// The container that nested lifetime scopes will be create from. /// A implementation for /// creating new lifetime scopes. public AutofacDependencyResolver(ILifetimeScope container, ILifetimeScopeProvider lifetimeScopeProvider) : this(container) { if (lifetimeScopeProvider == null) throw new ArgumentNullException("lifetimeScopeProvider"); _lifetimeScopeProvider = lifetimeScopeProvider; } /// /// Initializes a new instance of the class. /// /// The container that nested lifetime scopes will be create from. /// A implementation for /// creating new lifetime scopes. /// Action on a /// that adds component registations visible only in nested lifetime scopes. public AutofacDependencyResolver(ILifetimeScope container, ILifetimeScopeProvider lifetimeScopeProvider, Action configurationAction) : this(container, lifetimeScopeProvider) { if (configurationAction == null) throw new ArgumentNullException("configurationAction"); _configurationAction = configurationAction; } /// /// Gets the Autofac implementation of the dependency resolver. /// public static AutofacDependencyResolver Current { get { // Issue 351: We can't necessarily cast the current dependency resolver // to AutofacDependencyResolver because diagnostic systems like Glimpse // will wrap/proxy the resolver. Instead we need to register the resolver // on the fly with the request lifetime scope and resolve it accordingly. return DependencyResolver.Current.GetService(); } } /// /// The lifetime containing components for processing the current HTTP request. /// public ILifetimeScope RequestLifetimeScope { get { // Issue 351: Register the AutofacDependencyResolver with // the request lifetime scope so the current resolver can // be retrieved without having to cast it directly to // this specific type. Action composite = builder => { if (this._configurationAction != null) { this._configurationAction(builder); } builder.RegisterInstance(this).As(); }; if (_lifetimeScopeProvider == null) { _lifetimeScopeProvider = new RequestLifetimeScopeProvider(_container); } return _lifetimeScopeProvider.GetLifetimeScope(composite); } } /// /// Gets the application container that was provided to the constructor. /// public ILifetimeScope ApplicationContainer { get { return _container; } } /// /// Get a single instance of a service. /// /// Type of the service. /// The single instance if resolved; otherwise, null. public object GetService(Type serviceType) { return RequestLifetimeScope.ResolveOptional(serviceType); } /// /// Gets all available instances of a services. /// /// Type of the service. /// The list of instances if any were resolved; otherwise, an empty list. public IEnumerable GetServices(Type serviceType) { var enumerableServiceType = typeof(IEnumerable<>).MakeGenericType(serviceType); var instance = RequestLifetimeScope.Resolve(enumerableServiceType); return (IEnumerable)instance; } } }