<PackageReference Include="Castle.Windsor" Version="4.1.0" />

DefaultComponentActivator

Standard implementation of IComponentActivator. Handles the selection of the best constructor, fills the writable properties the component exposes, run the commission and decommission lifecycles, etc.
using Castle.Core; using Castle.Core.Internal; using Castle.DynamicProxy; using Castle.MicroKernel.Context; using System; using System.Reflection; using System.Runtime.Serialization; using System.Security; using System.Security.Permissions; namespace Castle.MicroKernel.ComponentActivator { [Serializable] public class DefaultComponentActivator : AbstractComponentActivator { private readonly bool useFastCreateInstance; public DefaultComponentActivator(ComponentModel model, IKernelInternal kernel, ComponentInstanceDelegate onCreation, ComponentInstanceDelegate onDestruction) : base(model, kernel, onCreation, onDestruction) { useFastCreateInstance = (!model.Implementation.IsContextful && ((IPermission)new SecurityPermission(SecurityPermissionFlag.SerializationFormatter)).IsGranted()); } protected override object InternalCreate(CreationContext context) { object obj = Instantiate(context); context.SetContextualProperty(this, obj); SetUpProperties(obj, context); ApplyCommissionConcerns(obj); return obj; } protected override void InternalDestroy(object instance) { ApplyDecommissionConcerns(instance); } protected virtual object Instantiate(CreationContext context) { ConstructorCandidate constructor = SelectEligibleConstructor(context); object[] arguments = CreateConstructorArguments(constructor, context); return CreateInstance(context, constructor, arguments); } protected virtual object CreateInstance(CreationContext context, ConstructorCandidate constructor, object[] arguments) { object obj = null; Type implementation = base.Model.Implementation; bool num = base.Kernel.ProxyFactory.ShouldCreateProxy(base.Model); if (!num && base.Model.Implementation.GetTypeInfo().IsAbstract) throw new ComponentRegistrationException(string.Format("Type {0} is abstract.{2} As such, it is not possible to instansiate it as implementation of service '{1}'. Did you forget to proxy it?", base.Model.Implementation.FullName, base.Model.Name, Environment.NewLine)); bool flag = true; if (num) flag = base.Kernel.ProxyFactory.RequiresTargetInstance(base.Kernel, base.Model); if (flag) obj = CreateInstanceCore(constructor, arguments, implementation); if (num) try { return base.Kernel.ProxyFactory.Create(base.Kernel, obj, base.Model, context, arguments); } catch (Exception innerException) { if (arguments != null) { foreach (object instance in arguments) { base.Kernel.ReleaseComponent(instance); } } throw new ComponentActivatorException("ComponentActivator: could not proxy " + base.Model.Implementation.FullName, innerException, base.Model); } return obj; } protected object CreateInstanceCore(ConstructorCandidate constructor, object[] arguments, Type implType) { try { if (!useFastCreateInstance) return implType.CreateInstance<object>(arguments); return FastCreateInstance(implType, arguments, constructor); } catch (Exception ex) { if (arguments != null) { foreach (object instance in arguments) { base.Kernel.ReleaseComponent(instance); } } if (ex is ComponentActivatorException) throw; throw new ComponentActivatorException("ComponentActivator: could not instantiate " + base.Model.Implementation.FullName, ex, base.Model); } } [SecuritySafeCritical] private object FastCreateInstance(Type implType, object[] arguments, ConstructorCandidate constructor) { if (constructor == null || constructor.Constructor == (ConstructorInfo)null) throw new ComponentActivatorException(string.Format("Could not find a public constructor for type {0}.{1}Windsor by default cannot instantiate types that don't expose public constructors.{1}To expose the type as a service add public constructor, or use custom component activator.", implType, Environment.NewLine), base.Model); object uninitializedObject = FormatterServices.GetUninitializedObject(implType); constructor.Constructor.Invoke(uninitializedObject, arguments); return uninitializedObject; } protected virtual ConstructorCandidate SelectEligibleConstructor(CreationContext context) { if (base.Model.Constructors.Count == 0) return null; if (base.Model.Constructors.Count == 1) return base.Model.Constructors[0]; ConstructorCandidate constructorCandidate = null; int winnerPoints = 0; foreach (ConstructorCandidate constructor in base.Model.Constructors) { if (CheckCtorCandidate(constructor, context, out int candidatePoints) && BestScoreSoFar(candidatePoints, winnerPoints, constructorCandidate)) { if (BestPossibleScore(constructor, candidatePoints)) return constructor; constructorCandidate = constructor; winnerPoints = candidatePoints; } } if (constructorCandidate == null) throw new NoResolvableConstructorFoundException(base.Model.Implementation, base.Model); return constructorCandidate; } private static bool BestScoreSoFar(int candidatePoints, int winnerPoints, ConstructorCandidate winnerCandidate) { if (winnerCandidate != null) return winnerPoints < candidatePoints; return true; } private static bool BestPossibleScore(ConstructorCandidate candidate, int candidatePoints) { return candidatePoints == candidate.Dependencies.Length * 100; } private bool CheckCtorCandidate(ConstructorCandidate candidate, CreationContext context, out int candidatePoints) { candidatePoints = 0; ConstructorDependencyModel[] dependencies = candidate.Dependencies; foreach (ConstructorDependencyModel constructorDependencyModel in dependencies) { if (CanSatisfyDependency(context, constructorDependencyModel)) candidatePoints += 100; else { if (!constructorDependencyModel.HasDefaultValue) { candidatePoints = 0; return false; } candidatePoints++; } } return true; } protected virtual bool CanSatisfyDependency(CreationContext context, DependencyModel dependency) { return base.Kernel.Resolver.CanResolve(context, context.Handler, base.Model, dependency); } protected virtual object[] CreateConstructorArguments(ConstructorCandidate constructor, CreationContext context) { if (constructor == null) return null; int num = constructor.Dependencies.Length; if (num != 0) { object[] array = new object[num]; try { for (int i = 0; i < num; i++) { array[i] = base.Kernel.Resolver.Resolve(context, context.Handler, base.Model, constructor.Dependencies[i]); } return array; } catch { object[] array2 = array; foreach (object instance in array2) { base.Kernel.ReleaseComponent(instance); } throw; } } return null; } protected virtual void SetUpProperties(object instance, CreationContext context) { instance = ProxyUtil.GetUnproxiedInstance(instance); IDependencyResolver resolver = base.Kernel.Resolver; foreach (PropertySet property in base.Model.Properties) { object obj = ObtainPropertyValue(context, property, resolver); if (obj != null) { MethodInfo setMethod = property.Property.GetSetMethod(); try { setMethod.Invoke(instance, new object[1] { obj }); } catch (Exception innerException) { throw new ComponentActivatorException(string.Format("Error setting property {1}.{0} in component {2}. See inner exception for more information.{4}If you don't want Windsor to set this property you can do it by either decorating it with {3} or via registration API.{4}Alternatively consider making the setter non-public.", property.Property.Name, instance.GetType().Name, base.Model.Name, typeof(DoNotWireAttribute).Name, Environment.NewLine), innerException, base.Model); } } } } private object ObtainPropertyValue(CreationContext context, PropertySet property, IDependencyResolver resolver) { if (!property.Dependency.IsOptional || resolver.CanResolve(context, context.Handler, base.Model, property.Dependency)) try { return resolver.Resolve(context, context.Handler, base.Model, property.Dependency); } catch (Exception exception) { if (!property.Dependency.IsOptional) throw; base.Kernel.Logger.Warn($"""{property.Dependency}""{base.Model.Name}""", exception); } return null; } } }