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

DefaultDependencyResolver

Default implementation for IDependencyResolver. This implementation is quite simple, but still should be useful for 99% of situations.
using Castle.Core; using Castle.Core.Internal; using Castle.MicroKernel.Context; using Castle.MicroKernel.Handlers; using Castle.MicroKernel.SubSystems.Conversion; using System; using System.Collections.Generic; using System.Linq; using System.Reflection; namespace Castle.MicroKernel.Resolvers { [Serializable] public class DefaultDependencyResolver : IDependencyResolver, ISubDependencyResolver { private readonly IList<ISubDependencyResolver> subResolvers = new List<ISubDependencyResolver>(); private ITypeConverter converter; private DependencyDelegate dependencyResolvingDelegate; private IKernelInternal kernel; public void AddSubResolver(ISubDependencyResolver subResolver) { if (subResolver == null) throw new ArgumentNullException("subResolver"); subResolvers.Add(subResolver); } public void Initialize(IKernelInternal kernel, DependencyDelegate dependencyDelegate) { this.kernel = kernel; converter = kernel.GetConversionManager(); dependencyResolvingDelegate = dependencyDelegate; } public void RemoveSubResolver(ISubDependencyResolver subResolver) { subResolvers.Remove(subResolver); } public bool CanResolve(CreationContext context, ISubDependencyResolver contextHandlerResolver, ComponentModel model, DependencyModel dependency) { if (CanResolveFromContext(context, contextHandlerResolver, model, dependency)) return true; if (CanResolveFromHandler(context, contextHandlerResolver, model, dependency)) return true; if (CanResolveFromContextHandlerResolver(context, contextHandlerResolver, model, dependency)) return true; if (CanResolveFromSubResolvers(context, contextHandlerResolver, model, dependency)) return true; return CanResolveFromKernel(context, model, dependency); } public object Resolve(CreationContext context, ISubDependencyResolver contextHandlerResolver, ComponentModel model, DependencyModel dependency) { if (!TryResolveCore(context, contextHandlerResolver, model, dependency, out object value)) { if (dependency.HasDefaultValue) value = dependency.DefaultValue; else if (!dependency.IsOptional) { throw new DependencyResolverException(string.Format("Could not resolve non-optional dependency for '{0}' ({1}). Parameter '{2}' type '{3}'", model.Name, (model.Implementation != (Type)null) ? model.Implementation.FullName : "-unknown-", dependency.DependencyKey, dependency.TargetType.FullName)); } } dependencyResolvingDelegate(model, dependency, value); return value; } protected virtual bool CanResolveFromKernel(CreationContext context, ComponentModel model, DependencyModel dependency) { if (dependency.ReferencedComponentName != null) return HasComponentInValidState(dependency.ReferencedComponentName, dependency, context); if (dependency.Parameter != null) return true; if (typeof(IKernel).IsAssignableFrom(dependency.TargetItemType)) return true; if (dependency.TargetItemType.IsPrimitiveType()) return false; return HasAnyComponentInValidState(dependency.TargetItemType, dependency, context); } protected virtual CreationContext RebuildContextForParameter(CreationContext current, Type parameterType) { if (parameterType.GetTypeInfo().ContainsGenericParameters) return current; return new CreationContext(parameterType, current, false); } protected virtual object ResolveFromKernel(CreationContext context, ComponentModel model, DependencyModel dependency) { if (dependency.ReferencedComponentName != null) return ResolveFromKernelByName(context, model, dependency); if (dependency.Parameter != null) return ResolveFromParameter(context, model, dependency); if (typeof(IKernel).IsAssignableFrom(dependency.TargetItemType)) return kernel; if (dependency.TargetItemType.IsPrimitiveType()) return null; return ResolveFromKernelByType(context, model, dependency); } private bool CanResolveFromContext(CreationContext context, ISubDependencyResolver contextHandlerResolver, ComponentModel model, DependencyModel dependency) { return context?.CanResolve(context, contextHandlerResolver, model, dependency) ?? false; } private bool CanResolveFromContextHandlerResolver(CreationContext context, ISubDependencyResolver contextHandlerResolver, ComponentModel model, DependencyModel dependency) { return contextHandlerResolver?.CanResolve(context, contextHandlerResolver, model, dependency) ?? false; } private bool CanResolveFromHandler(CreationContext context, ISubDependencyResolver contextHandlerResolver, ComponentModel model, DependencyModel dependency) { IHandler handler = kernel.GetHandler(model.Name); if (handler != null && handler != contextHandlerResolver) return handler.CanResolve(context, contextHandlerResolver, model, dependency); return false; } private bool CanResolveFromSubResolvers(CreationContext context, ISubDependencyResolver contextHandlerResolver, ComponentModel model, DependencyModel dependency) { if (subResolvers.Count > 0) return subResolvers.Any((ISubDependencyResolver s) => s.CanResolve(context, contextHandlerResolver, model, dependency)); return false; } private bool HasAnyComponentInValidState(Type service, DependencyModel dependency, CreationContext context) { IHandler handler2 = (context == null || !context.IsResolving) ? kernel.GetHandler(service) : kernel.LoadHandlerByType(dependency.DependencyKey, service, context.AdditionalArguments); if (handler2 == null) return false; if ((context == null || !handler2.IsBeingResolvedInContext(context)) && IsHandlerInValidState(handler2)) return true; List<IHandler> list = (from handler in kernel.GetHandlers(service) where !handler.IsBeingResolvedInContext(context) select handler).ToList(); RebuildOpenGenericHandlersWithClosedGenericSubHandlers(service, context, list); return list.Any((IHandler handler) => IsHandlerInValidState(handler)); } private void RebuildOpenGenericHandlersWithClosedGenericSubHandlers(Type service, CreationContext context, List<IHandler> nonResolvingHandlers) { if (context.RequestedType != (Type)null && service.GetTypeInfo().IsGenericType) { List<DefaultGenericHandler> genericHandlers = nonResolvingHandlers.OfType<DefaultGenericHandler>().ToList(); nonResolvingHandlers.RemoveAll((IHandler x) => genericHandlers.Contains(x)); CreationContext openGenericContext = RebuildContextForParameter(context, service); List<IHandler> collection = (from x in genericHandlers select x.ConvertToClosedGenericHandler(service, openGenericContext)).ToList(); nonResolvingHandlers.AddRange(collection); } } private bool HasComponentInValidState(string key, DependencyModel dependency, CreationContext context) { IHandler handler = (context == null || !context.IsResolving) ? kernel.GetHandler(key) : kernel.LoadHandlerByName(key, dependency.TargetItemType, context.AdditionalArguments); if (IsHandlerInValidState(handler)) return !handler.IsBeingResolvedInContext(context); return false; } private bool TryResolveCore(CreationContext context, ISubDependencyResolver contextHandlerResolver, ComponentModel model, DependencyModel dependency, out object value) { if (CanResolveFromContext(context, contextHandlerResolver, model, dependency)) { value = context.Resolve(context, contextHandlerResolver, model, dependency); return true; } IHandler handler = kernel.GetHandler(model.Name); if (handler != contextHandlerResolver && handler.CanResolve(context, contextHandlerResolver, model, dependency)) { value = handler.Resolve(context, contextHandlerResolver, model, dependency); return true; } if (CanResolveFromContextHandlerResolver(context, contextHandlerResolver, model, dependency)) { value = contextHandlerResolver.Resolve(context, contextHandlerResolver, model, dependency); return true; } if (subResolvers.Count > 0) { for (int i = 0; i < subResolvers.Count; i++) { ISubDependencyResolver subDependencyResolver = subResolvers[i]; if (subDependencyResolver.CanResolve(context, contextHandlerResolver, model, dependency)) { value = subDependencyResolver.Resolve(context, contextHandlerResolver, model, dependency); return true; } } } value = ResolveFromKernel(context, model, dependency); return value != null; } private object ResolveFromKernelByName(CreationContext context, ComponentModel model, DependencyModel dependency) { IHandler handler = kernel.LoadHandlerByName(dependency.ReferencedComponentName, dependency.TargetItemType, context.AdditionalArguments); if (handler == null) throw new DependencyResolverException(string.Format("Missing dependency.{2}Component {0} has a dependency on component {1}, which was not registered.{2}Make sure the dependency is correctly registered in the container as a service.", model.Name, dependency.ReferencedComponentName, Environment.NewLine)); CreationContext context2 = RebuildContextForParameter(context, dependency.TargetItemType); return handler.Resolve(context2); } private object ResolveFromKernelByType(CreationContext context, ComponentModel model, DependencyModel dependency) { if (!TryGetHandlerFromKernel(dependency, context, out IHandler handler)) { if (dependency.HasDefaultValue) return dependency.DefaultValue; throw new DependencyResolverException(string.Format("Missing dependency.{2}Component {0} has a dependency on {1}, which could not be resolved.{2}Make sure the dependency is correctly registered in the container as a service, or provided as inline argument.", model.Name, dependency.TargetItemType, Environment.NewLine)); } if (handler == null) { if (dependency.HasDefaultValue) return dependency.DefaultValue; throw new DependencyResolverException(string.Format("Cycle detected in configuration.{2}Component {0} has a dependency on {1}, but it doesn't provide an override.{2}You must provide an override if a component has a dependency on a service that it - itself - provides.", model.Name, dependency.TargetItemType, Environment.NewLine)); } context = RebuildContextForParameter(context, dependency.TargetItemType); return handler.Resolve(context); } private object ResolveFromParameter(CreationContext context, ComponentModel model, DependencyModel dependency) { converter.Context.Push(model, context); try { if (dependency.Parameter.Value == null && (object)dependency.Parameter.ConfigValue != null) return converter.PerformConversion(dependency.Parameter.ConfigValue, dependency.TargetItemType); return converter.PerformConversion(dependency.Parameter.Value, dependency.TargetItemType); } catch (ConverterException innerException) { throw new DependencyResolverException($"""{dependency.Parameter.Name}""{dependency.TargetItemType.Name}""", innerException); } finally { converter.Context.Pop(); } } private bool TryGetHandlerFromKernel(DependencyModel dependency, CreationContext context, out IHandler handler) { try { handler = kernel.LoadHandlerByType(dependency.DependencyKey, dependency.TargetItemType, context.AdditionalArguments); } catch (HandlerException) { handler = null; } if (handler == null) return false; if (!handler.IsBeingResolvedInContext(context)) return true; IHandler[] handlers; try { handlers = kernel.GetHandlers(dependency.TargetItemType); } catch (HandlerException) { return false; } IHandler[] array = handlers; foreach (IHandler handler2 in array) { if (!handler2.IsBeingResolvedInContext(context)) { handler = handler2; break; } } return true; } private static bool IsHandlerInValidState(IHandler handler) { if (handler == null) return false; return handler.CurrentState == HandlerState.Valid; } } }