ComponentRegistration<TService>
Registration for a single type as a component with the kernel.
You can create a new registration with the Component factory.
using Castle.Core;
using Castle.Core.Configuration;
using Castle.Core.Internal;
using Castle.DynamicProxy;
using Castle.MicroKernel.ComponentActivator;
using Castle.MicroKernel.Context;
using Castle.MicroKernel.Handlers;
using Castle.MicroKernel.LifecycleConcerns;
using Castle.MicroKernel.Lifestyle.Scoped;
using Castle.MicroKernel.ModelBuilder;
using Castle.MicroKernel.ModelBuilder.Descriptors;
using Castle.MicroKernel.Registration.Interceptor;
using Castle.MicroKernel.Registration.Lifestyle;
using Castle.MicroKernel.Registration.Proxy;
using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Reflection;
namespace Castle.MicroKernel.Registration
{
public class ComponentRegistration<TService> : IRegistration where TService : class
{
private readonly List<IComponentModelDescriptor> descriptors = new List<IComponentModelDescriptor>();
private readonly List<Type> potentialServices = new List<Type>();
private readonly HashSet<Type> potentialServicesLookup = new HashSet<Type>();
private bool ifComponentRegisteredIgnore;
private Type implementation;
private ComponentName name;
private bool overwrite;
private bool registerNewServicesOnly;
private bool registered;
public Type Implementation => implementation;
[EditorBrowsable(EditorBrowsableState.Advanced)]
public LifestyleGroup<TService> LifeStyle {
get {
return new LifestyleGroup<TService>(this);
}
}
public string Name {
get {
if (name == null)
return null;
return name.Name;
}
}
public ProxyGroup<TService> Proxy => new ProxyGroup<TService>(this);
protected internal IList<Type> Services => potentialServices;
protected internal int ServicesCount => potentialServices.Count;
internal bool IsOverWrite => overwrite;
public ComponentRegistration()
: this(new Type[1] {
typeof(TService)
})
{
}
public ComponentRegistration(params Type[] services)
{
Forward(services);
}
public ComponentRegistration<TService> Activator<TActivator>() where TActivator : IComponentActivator
{
return this.AddAttributeDescriptor("componentActivatorType", typeof(TActivator).AssemblyQualifiedName);
}
public ComponentRegistration<TService> AddAttributeDescriptor(string key, string value)
{
AddDescriptor(new AttributeDescriptor<TService>(key, value));
return this;
}
public ComponentRegistration<TService> AddDescriptor(IComponentModelDescriptor descriptor)
{
descriptors.Add(descriptor);
AbstractOverwriteableDescriptor<TService> abstractOverwriteableDescriptor = descriptor as AbstractOverwriteableDescriptor<TService>;
if (abstractOverwriteableDescriptor != null)
abstractOverwriteableDescriptor.Registration = this;
return this;
}
public AttributeKeyDescriptor<TService> Attribute(string key)
{
return new AttributeKeyDescriptor<TService>(this, key);
}
public ComponentRegistration<TService> Configuration(params Node[] configNodes)
{
return AddDescriptor(new ConfigurationDescriptor(configNodes));
}
public ComponentRegistration<TService> Configuration(IConfiguration configuration)
{
return AddDescriptor(new ConfigurationDescriptor(configuration));
}
public ComponentRegistration<TService> DependsOn(Dependency dependency)
{
return DependsOn(new Dependency[1] {
dependency
});
}
public ComponentRegistration<TService> DependsOn(params Dependency[] dependencies)
{
if (dependencies == null || dependencies.Length == 0)
return this;
List<ServiceOverride> list = new List<ServiceOverride>(dependencies.Length);
List<Property> list2 = new List<Property>(dependencies.Length);
List<Parameter> list3 = new List<Parameter>(dependencies.Length);
foreach (Dependency dependency in dependencies) {
if (!dependency.Accept<Property>((ICollection<Property>)list2) && !dependency.Accept<Parameter>((ICollection<Parameter>)list3))
dependency.Accept<ServiceOverride>((ICollection<ServiceOverride>)list);
}
if (list.Count > 0)
AddDescriptor(new ServiceOverrideDescriptor(list.ToArray()));
if (list2.Count > 0)
AddDescriptor(new CustomDependencyDescriptor(list2.ToArray()));
if (list3.Count > 0)
AddDescriptor(new ParametersDescriptor(list3.ToArray()));
return this;
}
public ComponentRegistration<TService> DependsOn(Arguments dependencies)
{
return AddDescriptor(new CustomDependencyDescriptor(dependencies));
}
public ComponentRegistration<TService> DependsOn(IDictionary dependencies)
{
Arguments arguments = new Arguments();
IDictionaryEnumerator enumerator = dependencies.GetEnumerator();
try {
while (enumerator.MoveNext()) {
DictionaryEntry dictionaryEntry = (DictionaryEntry)enumerator.Current;
arguments.Add(dictionaryEntry.Key, dictionaryEntry.Value);
}
} finally {
(enumerator as IDisposable)?.Dispose();
}
return DependsOn(arguments);
}
public ComponentRegistration<TService> DependsOn(object dependenciesAsAnonymousType)
{
return DependsOn((IDictionary)new ReflectionBasedDictionaryAdapter(dependenciesAsAnonymousType));
}
public ComponentRegistration<TService> DependsOn(DynamicParametersDelegate resolve)
{
return DynamicParameters(delegate(IKernel k, CreationContext c, Arguments d) {
resolve(k, d);
return null;
});
}
public ComponentRegistration<TService> DependsOn(DynamicParametersResolveDelegate resolve)
{
return DynamicParameters((IKernel k, CreationContext c, Arguments d) => resolve(k, d));
}
public ComponentRegistration<TService> DependsOn(DynamicParametersWithContextResolveDelegate resolve)
{
AddDescriptor(new DynamicParametersDescriptor(resolve));
return this;
}
public ComponentRegistration<TService> DynamicParameters(DynamicParametersDelegate resolve)
{
return DynamicParameters(delegate(IKernel k, CreationContext c, Arguments d) {
resolve(k, d);
return null;
});
}
public ComponentRegistration<TService> DynamicParameters(DynamicParametersResolveDelegate resolve)
{
return DynamicParameters((IKernel k, CreationContext c, Arguments d) => resolve(k, d));
}
public ComponentRegistration<TService> DynamicParameters(DynamicParametersWithContextResolveDelegate resolve)
{
AddDescriptor(new DynamicParametersDescriptor(resolve));
return this;
}
public ComponentRegistration<TService> ExtendedProperties(params Property[] properties)
{
return AddDescriptor(new ExtendedPropertiesDescriptor(properties));
}
public ComponentRegistration<TService> ExtendedProperties(Property property)
{
return ExtendedProperties(new Property[1] {
property
});
}
public ComponentRegistration<TService> ExtendedProperties(object anonymous)
{
return AddDescriptor(new ExtendedPropertiesDescriptor((IDictionary)new ReflectionBasedDictionaryAdapter(anonymous)));
}
public ComponentRegistration<TService> Forward(params Type[] types)
{
return Forward((IEnumerable<Type>)types);
}
public ComponentRegistration<TService> Forward<TService2>()
{
return this.Forward(new Type[1] {
typeof(TService2)
});
}
public ComponentRegistration<TService> Forward<TService2, TService3>()
{
return this.Forward(new Type[2] {
typeof(TService2),
typeof(TService3)
});
}
public ComponentRegistration<TService> Forward<TService2, TService3, TService4>()
{
return this.Forward(new Type[3] {
typeof(TService2),
typeof(TService3),
typeof(TService4)
});
}
public ComponentRegistration<TService> Forward<TService2, TService3, TService4, TService5>()
{
return this.Forward(new Type[4] {
typeof(TService2),
typeof(TService3),
typeof(TService4),
typeof(TService5)
});
}
public ComponentRegistration<TService> Forward(IEnumerable<Type> types)
{
foreach (Type type in types) {
ComponentServicesUtil.AddService(potentialServices, potentialServicesLookup, type);
}
return this;
}
public ComponentRegistration<TService> ImplementedBy<TImpl>() where TImpl : TService
{
return this.ImplementedBy(typeof(TImpl));
}
public ComponentRegistration<TService> ImplementedBy(Type type)
{
return ImplementedBy(type, null, null);
}
public ComponentRegistration<TService> ImplementedBy(Type type, IGenericImplementationMatchingStrategy genericImplementationMatchingStrategy)
{
return ImplementedBy(type, genericImplementationMatchingStrategy, null);
}
public ComponentRegistration<TService> ImplementedBy(Type type, IGenericServiceStrategy genericServiceStrategy)
{
return ImplementedBy(type, null, genericServiceStrategy);
}
public ComponentRegistration<TService> ImplementedBy(Type type, IGenericImplementationMatchingStrategy genericImplementationMatchingStrategy, IGenericServiceStrategy genericServiceStrategy)
{
if (implementation != (Type)null && implementation != typeof(LateBoundComponent))
throw new ComponentRegistrationException($"""{implementation.FullName}");
implementation = type;
if (genericImplementationMatchingStrategy != null)
ExtendedProperties(Property.ForKey(Constants.GenericImplementationMatchingStrategy).Eq(genericImplementationMatchingStrategy));
if (genericServiceStrategy != null)
ExtendedProperties(Property.ForKey(Constants.GenericServiceStrategy).Eq(genericServiceStrategy));
return this;
}
public ComponentRegistration<TService> Instance(TService instance)
{
if (instance == null)
throw new ArgumentNullException("instance");
return ImplementedBy(instance.GetType()).Activator<ExternalInstanceActivator>().ExtendedProperties(Property.ForKey("instance").Eq(instance));
}
public InterceptorGroup<TService> Interceptors(params InterceptorReference[] interceptors)
{
return new InterceptorGroup<TService>(this, interceptors);
}
public ComponentRegistration<TService> Interceptors(params Type[] interceptors)
{
InterceptorReference[] interceptors2 = EnumerableExtensions.ConvertAll<Type, InterceptorReference>(interceptors, (Func<Type, InterceptorReference>)((Type t) => new InterceptorReference(t)));
return AddDescriptor(new InterceptorDescriptor(interceptors2));
}
public ComponentRegistration<TService> Interceptors<TInterceptor>() where TInterceptor : IInterceptor
{
return this.AddDescriptor((IComponentModelDescriptor)new InterceptorDescriptor(new InterceptorReference[1] {
new InterceptorReference(typeof(TInterceptor))
}));
}
public ComponentRegistration<TService> Interceptors<TInterceptor1, TInterceptor2>() where TInterceptor1 : IInterceptor where TInterceptor2 : IInterceptor
{
return Interceptors<TInterceptor1>().Interceptors<TInterceptor2>();
}
public ComponentRegistration<TService> Interceptors(params string[] keys)
{
InterceptorReference[] interceptors = EnumerableExtensions.ConvertAll<string, InterceptorReference>(keys, (Func<string, InterceptorReference>)InterceptorReference.ForKey);
return AddDescriptor(new InterceptorDescriptor(interceptors));
}
public ComponentRegistration<TService> LifestyleCustom(Type customLifestyleType)
{
return LifeStyle.Custom(customLifestyleType);
}
public ComponentRegistration<TService> LifestyleCustom<TLifestyleManager>() where TLifestyleManager : ILifestyleManager, new
{
return this.LifeStyle.Custom<TLifestyleManager>();
}
public ComponentRegistration<TService> LifestylePerThread()
{
return LifeStyle.PerThread;
}
public ComponentRegistration<TService> LifestyleScoped(Type scopeAccessorType = null)
{
return LifeStyle.Scoped(scopeAccessorType);
}
public ComponentRegistration<TService> LifestyleScoped<TScopeAccessor>() where TScopeAccessor : IScopeAccessor, new
{
return this.LifestyleScoped(typeof(TScopeAccessor));
}
public ComponentRegistration<TService> LifestyleBoundTo<TBaseForRoot>() where TBaseForRoot : class
{
return this.LifeStyle.BoundTo<TBaseForRoot>();
}
public ComponentRegistration<TService> LifestyleBoundToNearest<TBaseForRoot>() where TBaseForRoot : class
{
return this.LifeStyle.BoundToNearest<TBaseForRoot>();
}
public ComponentRegistration<TService> LifestyleBoundTo(Func<IHandler[], IHandler> scopeRootBinder)
{
return LifeStyle.BoundTo(scopeRootBinder);
}
public ComponentRegistration<TService> LifestylePooled(int? initialSize = default(int?), int? maxSize = default(int?))
{
return LifeStyle.PooledWithSize(initialSize, maxSize);
}
public ComponentRegistration<TService> LifestyleSingleton()
{
return LifeStyle.Singleton;
}
public ComponentRegistration<TService> LifestyleTransient()
{
return LifeStyle.Transient;
}
public ComponentRegistration<TService> Named(string name)
{
if (this.name != null)
throw new ComponentRegistrationException($"""{this.name.Name}""");
if (name == null)
return this;
this.name = new ComponentName(name, true);
return this;
}
public ComponentRegistration<TService> NamedAutomatically(string name)
{
if (this.name != null)
throw new ComponentRegistrationException($"""{this.name}""");
this.name = new ComponentName(name, false);
return this;
}
public ComponentRegistration<TService> OnCreate(params Action<TService>[] actions)
{
if (actions != null && actions.Length != 0)
return OnCreate(EnumerableExtensions.ConvertAll<Action<TService>, LifecycleActionDelegate<TService>>(actions, (Func<Action<TService>, LifecycleActionDelegate<TService>>)((Action<TService> a) => delegate(IKernel _, TService o) {
a(o);
})));
return this;
}
public ComponentRegistration<TService> OnCreate(params LifecycleActionDelegate<TService>[] actions)
{
if (actions != null && actions.Length != 0) {
LifecycleActionDelegate<TService> action = (LifecycleActionDelegate<TService>)Delegate.Combine(actions);
AddDescriptor(new OnCreateComponentDescriptor<TService>(action));
}
return this;
}
public ComponentRegistration<TService> OnDestroy(params Action<TService>[] actions)
{
if (actions != null && actions.Length != 0)
return OnDestroy(EnumerableExtensions.ConvertAll<Action<TService>, LifecycleActionDelegate<TService>>(actions, (Func<Action<TService>, LifecycleActionDelegate<TService>>)((Action<TService> a) => delegate(IKernel _, TService o) {
a(o);
})));
return this;
}
public ComponentRegistration<TService> OnDestroy(params LifecycleActionDelegate<TService>[] actions)
{
if (actions != null && actions.Length != 0) {
LifecycleActionDelegate<TService> action = (LifecycleActionDelegate<TService>)Delegate.Combine(actions);
AddDescriptor(new OnDestroyComponentDescriptor<TService>(action));
}
return this;
}
public ComponentRegistration<TService> OnlyNewServices()
{
registerNewServicesOnly = true;
return this;
}
[EditorBrowsable(EditorBrowsableState.Never)]
public ComponentRegistration<TService> OverWrite()
{
overwrite = true;
return this;
}
public ComponentRegistration<TService> SelectInterceptorsWith(IInterceptorSelector selector)
{
return SelectInterceptorsWith((Action<ItemRegistration<IInterceptorSelector>>)delegate(ItemRegistration<IInterceptorSelector> s) {
s.Instance(selector);
});
}
public ComponentRegistration<TService> SelectInterceptorsWith(Action<ItemRegistration<IInterceptorSelector>> selector)
{
ItemRegistration<IInterceptorSelector> itemRegistration = new ItemRegistration<IInterceptorSelector>();
selector(itemRegistration);
return AddDescriptor(new InterceptorSelectorDescriptor(itemRegistration.Item));
}
public ComponentRegistration<TService> UsingFactory<TFactory, TServiceImpl>(Func<TFactory, TServiceImpl> factory) where TServiceImpl : TService
{
return UsingFactoryMethod((IKernel kernel) => factory(kernel.Resolve<TFactory>()), false);
}
public ComponentRegistration<TService> UsingFactoryMethod<TImpl>(Func<TImpl> factoryMethod, bool managedExternally = false) where TImpl : TService
{
return UsingFactoryMethod((IKernel k, ComponentModel m, CreationContext c) => factoryMethod(), managedExternally);
}
public ComponentRegistration<TService> UsingFactoryMethod<TImpl>(Func<IKernel, TImpl> factoryMethod, bool managedExternally = false) where TImpl : TService
{
return UsingFactoryMethod((IKernel k, ComponentModel m, CreationContext c) => factoryMethod(k), managedExternally);
}
public ComponentRegistration<TService> UsingFactoryMethod<TImpl>(Func<IKernel, ComponentModel, CreationContext, TImpl> factoryMethod, bool managedExternally = false) where TImpl : TService
{
Activator<FactoryMethodActivator<TImpl>>().ExtendedProperties(Property.ForKey("factoryMethodDelegate").Eq(factoryMethod));
if (managedExternally)
this.ExtendedProperties(Property.ForKey("factory.managedExternally").Eq(managedExternally));
if (this.implementation == (Type)null && (!Enumerable.First<Type>((IEnumerable<Type>)this.potentialServices).GetTypeInfo().IsClass || !Enumerable.First<Type>((IEnumerable<Type>)this.potentialServices).GetTypeInfo().IsSealed))
this.implementation = typeof(LateBoundComponent);
return this;
}
public ComponentRegistration<TService> UsingFactoryMethod<TImpl>(Func<IKernel, CreationContext, TImpl> factoryMethod) where TImpl : TService
{
return UsingFactoryMethod((IKernel k, ComponentModel m, CreationContext c) => factoryMethod(k, c), false);
}
internal void RegisterOptionally()
{
ifComponentRegisteredIgnore = true;
}
private Type[] FilterServices(IKernel kernel)
{
List<Type> list = new List<Type>(potentialServices);
if (registerNewServicesOnly)
list.RemoveAll(kernel.HasComponent);
return list.ToArray();
}
private IComponentModelDescriptor[] GetContributors(Type[] services)
{
List<IComponentModelDescriptor> list = new List<IComponentModelDescriptor>();
list.Add(new ServicesDescriptor(services));
list.Add(new DefaultsDescriptor(name, implementation));
list.AddRange(descriptors);
return list.ToArray();
}
private bool SkipRegistration(IKernelInternal internalKernel, ComponentModel componentModel)
{
if (ifComponentRegisteredIgnore)
return internalKernel.HasComponent(componentModel.Name);
return false;
}
void IRegistration.Register(IKernelInternal kernel)
{
if (!registered) {
registered = true;
Type[] array = FilterServices(kernel);
if (array.Length != 0) {
ComponentModel componentModel = kernel.ComponentModelBuilder.BuildModel(GetContributors(array));
if (SkipRegistration(kernel, componentModel))
kernel.Logger.Info("Skipping registration of " + componentModel.Name);
else
kernel.AddCustomComponent(componentModel);
}
}
}
public ComponentRegistration<TService> IsDefault(Predicate<Type> serviceFilter)
{
if (serviceFilter == null)
throw new ArgumentNullException("serviceFilter");
Property property = new Property(Constants.DefaultComponentForServiceFilter, serviceFilter);
return ExtendedProperties(property);
}
public ComponentRegistration<TService> IsDefault()
{
return IsDefault((Type _) => true);
}
public ComponentRegistration<TService> IsFallback(Predicate<Type> serviceFilter)
{
if (serviceFilter == null)
throw new ArgumentNullException("serviceFilter");
Property property = new Property(Constants.FallbackComponentForServiceFilter, serviceFilter);
return ExtendedProperties(property);
}
public ComponentRegistration<TService> IsFallback()
{
return IsFallback((Type _) => true);
}
public ComponentRegistration<TService> PropertiesIgnore(Func<PropertyInfo, bool> propertySelector)
{
return PropertiesIgnore((ComponentModel _, PropertyInfo p) => propertySelector(p));
}
public ComponentRegistration<TService> PropertiesRequire(Func<PropertyInfo, bool> propertySelector)
{
return PropertiesRequire((ComponentModel _, PropertyInfo p) => propertySelector(p));
}
public ComponentRegistration<TService> PropertiesIgnore(Func<ComponentModel, PropertyInfo, bool> propertySelector)
{
return AddDescriptor(new DelegatingModelDescriptor(delegate(IKernel k, ComponentModel c) {
StandardPropertyFilters.GetPropertyFilters(c, true).Add(StandardPropertyFilters.IgnoreSelected(propertySelector));
}, null));
}
public ComponentRegistration<TService> PropertiesRequire(Func<ComponentModel, PropertyInfo, bool> propertySelector)
{
return AddDescriptor(new DelegatingModelDescriptor(delegate(IKernel k, ComponentModel c) {
StandardPropertyFilters.GetPropertyFilters(c, true).Add(StandardPropertyFilters.RequireSelected(propertySelector));
}, null));
}
public ComponentRegistration<TService> Properties(PropertyFilter filter)
{
return AddDescriptor(new DelegatingModelDescriptor(delegate(IKernel k, ComponentModel c) {
StandardPropertyFilters.GetPropertyFilters(c, true).Add(StandardPropertyFilters.Create(filter));
}, null));
}
}
}