PageRenderTime 23ms CodeModel.GetById 12ms app.highlight 8ms RepoModel.GetById 1ms app.codeStats 0ms

/src/LinFu.IoC/ServiceContainer.cs

http://github.com/philiplaureano/LinFu
C# | 192 lines | 71 code | 23 blank | 98 comment | 18 complexity | bcef616fc80bea25210511c0ac3e8b3c MD5 | raw file
  1using System;
  2using System.Collections.Generic;
  3using System.Security;
  4using LinFu.IoC.Interfaces;
  5
  6namespace LinFu.IoC
  7{
  8    /// <summary>
  9    ///     Represents a service container with additional
 10    ///     extension points for customizing service instances
 11    /// </summary>
 12    [SecurityCritical]
 13    public class ServiceContainer : IServiceContainer
 14    {
 15        private readonly IGetService _getServiceBehavior;
 16        private readonly List<IPostProcessor> _postProcessors = new List<IPostProcessor>();
 17        private readonly List<IPreProcessor> _preprocessors = new List<IPreProcessor>();
 18
 19        /// <summary>
 20        ///     Initializes the container with the default services.
 21        /// </summary>
 22        public ServiceContainer()
 23        {
 24            _getServiceBehavior = new DefaultGetServiceBehavior(this);
 25            this.AddDefaultServices();
 26        }
 27
 28        /// <summary>
 29        ///     Initializes the container with a custom <see cref="ICreateInstance" /> type.
 30        /// </summary>
 31        /// <param name="getServiceBehavior">The instance that will be responsible for generating service instances.</param>
 32        /// <param name="factoryStorage">
 33        ///     The <see cref="IFactoryStorage" /> instance responsible for determining which factory
 34        ///     instance will instantiate a given service request.
 35        /// </param>
 36        public ServiceContainer(IGetService getServiceBehavior, IFactoryStorage factoryStorage)
 37        {
 38            if (getServiceBehavior == null)
 39                throw new ArgumentNullException("getServiceBehavior");
 40
 41            if (factoryStorage == null)
 42                throw new ArgumentNullException("factoryStorage");
 43
 44            _getServiceBehavior = getServiceBehavior;
 45            FactoryStorage = factoryStorage;
 46
 47            this.AddDefaultServices();
 48        }
 49
 50        /// <summary>
 51        ///     Gets the value indicating the <see cref="IFactoryStorage" /> instance
 52        ///     that will be used to store each <see cref="IFactory" /> instance.
 53        /// </summary>
 54        internal IFactoryStorage FactoryStorage { get; } = new FactoryStorage();
 55
 56
 57        /// <summary>
 58        ///     Gets or sets a <see cref="bool">System.Boolean</see> value
 59        ///     that determines whether or not the container should throw
 60        ///     a <see cref="ServiceNotFoundException" /> if a requested service
 61        ///     cannot be found or created.
 62        /// </summary>
 63        public virtual bool SuppressErrors { get; set; }
 64
 65        /// <summary>
 66        ///     Adds an <see cref="IFactory" /> instance and associates it
 67        ///     with the given <paramref name="serviceType">service type</paramref> and
 68        ///     <paramref name="serviceName">service name</paramref>.
 69        /// </summary>
 70        /// <param name="serviceName">The name of the service to associate with the given <see cref="IFactory" /> instance.</param>
 71        /// <param name="serviceType">The type of service that the factory will be able to create.</param>
 72        /// <param name="additionalParameterTypes">The list of additional parameters that this factory type will support.</param>
 73        /// <param name="factory">The <see cref="IFactory" /> instance that will create the object instance.</param>
 74        public virtual void AddFactory(string serviceName, Type serviceType, IEnumerable<Type> additionalParameterTypes,
 75            IFactory factory)
 76        {
 77            FactoryStorage.AddFactory(serviceName, serviceType, additionalParameterTypes, factory);
 78        }
 79
 80        /// <summary>
 81        ///     Adds an <see cref="IFactory" /> instance and associates it
 82        ///     with the given <paramref name="serviceType">service type</paramref>.
 83        /// </summary>
 84        /// <param name="serviceType">The service type to associate with the factory</param>
 85        /// <param name="additionalParameterTypes">The list of additional parameters that this factory type will support.</param>
 86        /// <param name="factory">The <see cref="IFactory" /> instance that will be responsible for creating the service instance</param>
 87        public virtual void AddFactory(Type serviceType, IEnumerable<Type> additionalParameterTypes, IFactory factory)
 88        {
 89            AddFactory(null, serviceType, additionalParameterTypes, factory);
 90        }
 91
 92        /// <summary>
 93        ///     Determines whether or not the given <paramref name="serviceType" />
 94        ///     can be instantiated by the container.
 95        /// </summary>
 96        /// <param name="serviceType">The type of service to instantiate.</param>
 97        /// <param name="additionalParameterTypes">The list of additional parameters that this factory type will support.</param>
 98        /// <returns>Returns <c>true</c> if the service exists; otherwise, it will return <c>false</c>.</returns>
 99        public virtual bool Contains(Type serviceType, IEnumerable<Type> additionalParameterTypes)
100        {
101            return Contains(null, serviceType, additionalParameterTypes);
102        }
103
104        /// <summary>
105        ///     Overridden. Causes the container to instantiate the service with the given
106        ///     <paramref name="serviceType">service type</paramref>. If the service type cannot be created, then an
107        ///     exception will be thrown if the <see cref="IContainer.SuppressErrors" /> property
108        ///     is set to false. Otherwise, it will simply return null.
109        /// </summary>
110        /// <remarks>
111        ///     This overload of the <c>GetService</c> method has been overridden
112        ///     so that its results can be handled by the postprocessors.
113        /// </remarks>
114        /// <seealso cref="IPostProcessor" />
115        /// <param name="serviceType">The service type to instantiate.</param>
116        /// <param name="additionalArguments">The additional arguments that will be used to instantiate the service type.</param>
117        /// <returns>
118        ///     If successful, it will return a service instance that is compatible with the given type;
119        ///     otherwise, it will just return a null value.
120        /// </returns>
121        public virtual object GetService(Type serviceType, params object[] additionalArguments)
122        {
123            return GetService(null, serviceType, additionalArguments);
124        }
125
126        /// <summary>
127        ///     Causes the container to instantiate the service with the given
128        ///     <paramref name="serviceType">service type</paramref>. If the service type cannot be created, then an
129        ///     exception will be thrown if the <see cref="IContainer.SuppressErrors" /> property
130        ///     is set to false. Otherwise, it will simply return null.
131        /// </summary>
132        /// <param name="serviceName">The name of the service to instantiate.</param>
133        /// <param name="serviceType">The service type to instantiate.</param>
134        /// <param name="additionalArguments">The additional arguments that will be used to instantiate the service type.</param>
135        /// <returns>
136        ///     If successful, it will return a service instance that is compatible with the given type;
137        ///     otherwise, it will just return a <c>null</c> value.
138        /// </returns>
139        public virtual object GetService(string serviceName, Type serviceType, params object[] additionalArguments)
140        {
141            IFactory factory = null;
142
143            if (FactoryStorage != null)
144                factory = FactoryStorage.GetFactory(serviceName, serviceType, additionalArguments);
145
146            var serviceRequest = new ServiceRequest(serviceName, serviceType, additionalArguments, factory, this);
147            var instance = _getServiceBehavior.GetService(serviceRequest);
148
149            if (SuppressErrors == false && instance == null && serviceName == null)
150                throw new ServiceNotFoundException(serviceType);
151
152            if (SuppressErrors == false && instance == null && serviceName != null)
153                throw new NamedServiceNotFoundException(serviceName, serviceType);
154
155            return instance;
156        }
157
158        /// <summary>
159        ///     Determines whether or not a service can be created using
160        ///     the given <paramref name="serviceName">service name</paramref>
161        ///     and <paramref name="serviceType">service type</paramref>.
162        /// </summary>
163        /// <param name="serviceName">The name of the service to associate with the given <see cref="IFactory" /> instance.</param>
164        /// <param name="serviceType">The type of service that the factory will be able to create.</param>
165        /// <param name="additionalParameterTypes">The list of additional parameters that this factory type will support.</param>
166        /// <returns>Returns <c>true</c> if the service exists; otherwise, it will return <c>false</c>.</returns>
167        public virtual bool Contains(string serviceName, Type serviceType, IEnumerable<Type> additionalParameterTypes)
168        {
169            return FactoryStorage.ContainsFactory(serviceName, serviceType, additionalParameterTypes);
170        }
171
172        /// <summary>
173        ///     The list of postprocessors that will handle every
174        ///     service request result.
175        /// </summary>
176        public virtual IList<IPostProcessor> PostProcessors => _postProcessors;
177
178        /// <summary>
179        ///     The list of preprocessors that will handle
180        ///     every service request before each actual service is created.
181        /// </summary>
182        public virtual IList<IPreProcessor> PreProcessors
183        {
184            get { return _preprocessors; }
185        }
186
187        /// <summary>
188        ///     The list of services currently available inside the container.
189        /// </summary>
190        public virtual IEnumerable<IServiceInfo> AvailableServices => FactoryStorage.AvailableFactories;
191    }
192}