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

ComponentProxyInspector

Inspects the component configuration and type looking for information that can influence the generation of a proxy for that component.

We specifically look for additionalInterfaces and marshalByRefProxy on the component configuration or the ComponentProxyBehaviorAttribute attribute.

using Castle.Core; using Castle.Core.Configuration; using Castle.Core.Internal; using Castle.MicroKernel.Proxy; using Castle.MicroKernel.SubSystems.Conversion; using System; using System.Collections.Generic; using System.Collections.Specialized; using System.Linq; namespace Castle.MicroKernel.ModelBuilder.Inspectors { [Serializable] public class ComponentProxyInspector : IContributeComponentModelConstruction { private readonly IConversionManager converter; public ComponentProxyInspector(IConversionManager converter) { this.converter = converter; } public virtual void ProcessModel(IKernel kernel, ComponentModel model) { ReadProxyBehavior(kernel, model); } protected virtual ComponentProxyBehaviorAttribute ReadProxyBehaviorFromType(Type implementation) { return implementation.GetAttributes<ComponentProxyBehaviorAttribute>().FirstOrDefault(); } protected virtual void ReadProxyBehavior(IKernel kernel, ComponentModel model) { ComponentProxyBehaviorAttribute componentProxyBehaviorAttribute = ReadProxyBehaviorFromType(model.Implementation); if (componentProxyBehaviorAttribute == null) componentProxyBehaviorAttribute = new ComponentProxyBehaviorAttribute(); ReadProxyBehaviorFromConfig(model, componentProxyBehaviorAttribute); ApplyProxyBehavior(componentProxyBehaviorAttribute, model); } private void ReadProxyBehaviorFromConfig(ComponentModel model, ComponentProxyBehaviorAttribute behavior) { if ((object)model.Configuration != null) { string text = ((NameValueCollection)model.Configuration.get_Attributes())["marshalByRefProxy"]; if (text != null) behavior.UseMarshalByRefProxy = converter.PerformConversion<bool?>(text).GetValueOrDefault(false); IConfiguration val = model.Configuration.get_Children().get_Item("additionalInterfaces"); if (val != null) { List<Type> list = new List<Type>(behavior.AdditionalInterfaces); foreach (IConfiguration item2 in (List<IConfiguration>)val.get_Children()) { string value = ((NameValueCollection)item2.get_Attributes())["interface"]; Type item = converter.PerformConversion<Type>(value); list.Add(item); } behavior.AdditionalInterfaces = list.ToArray(); } } } private static void ApplyProxyBehavior(ComponentProxyBehaviorAttribute behavior, ComponentModel model) { ProxyOptions proxyOptions = model.ObtainProxyOptions(true); if (behavior.UseMarshalByRefProxy) EnsureComponentRegisteredWithInterface(model); proxyOptions.UseMarshalByRefAsBaseClass = behavior.UseMarshalByRefProxy; proxyOptions.AddAdditionalInterfaces(behavior.AdditionalInterfaces); if (model.Implementation.IsInterface) proxyOptions.OmitTarget = true; } private static void EnsureComponentRegisteredWithInterface(ComponentModel model) { if (model.HasClassServices) { string message = $"""{model.Implementation.FullName}""{model.Services.First().FullName}"""; throw new ComponentRegistrationException(message); } } } }