From 014fbe1a80d1697308455351f5e3def67777f99c Mon Sep 17 00:00:00 2001 From: Travis Illig Date: Tue, 23 Jun 2026 17:06:15 -0700 Subject: [PATCH 1/2] Add conditional interception via type predicate (#42) Add a shouldIntercept predicate (Func) to both EnableClassInterceptors and EnableInterfaceInterceptors so interception can be applied selectively based on the implementation type. This is particularly useful with assembly scanning, where only some scanned types should be intercepted. For interface interception the predicate is evaluated at resolve time against the resolved implementation type; when it returns false the instance is returned without a proxy. For class interception the proxy type is generated at registration time, so the predicate is evaluated per type at registration; when it returns false the type is registered without interception. All new overloads are additive; existing signatures are unchanged to preserve binary compatibility. --- .../RegistrationExtensions.cs | 174 ++++++++++++++++- .../ConditionalInterceptionFixture.cs | 177 ++++++++++++++++++ 2 files changed, 346 insertions(+), 5 deletions(-) create mode 100644 test/Autofac.Extras.DynamicProxy.Test/ConditionalInterceptionFixture.cs diff --git a/src/Autofac.Extras.DynamicProxy/RegistrationExtensions.cs b/src/Autofac.Extras.DynamicProxy/RegistrationExtensions.cs index 222ed48..eb338da 100644 --- a/src/Autofac.Extras.DynamicProxy/RegistrationExtensions.cs +++ b/src/Autofac.Extras.DynamicProxy/RegistrationExtensions.cs @@ -39,6 +39,28 @@ public static IRegistrationBuilder + /// Enable class interception on the target type, conditionally based on the + /// implementation type. Interceptors will be determined via Intercept attributes + /// on the class or added with InterceptedBy(). Only virtual methods can be + /// intercepted this way. + /// + /// Registration limit type. + /// Registration style. + /// Registration to apply interception to. + /// + /// A predicate, evaluated against each candidate implementation type, that + /// determines whether interception is applied. Types for which the predicate + /// returns are registered without interception. + /// + /// Registration builder allowing the registration to be configured. + public static IRegistrationBuilder EnableClassInterceptors( + this IRegistrationBuilder registration, + Func shouldIntercept) + { + return EnableClassInterceptors(registration, ProxyGenerationOptions.Default, shouldIntercept); + } + /// /// Enable class interception on the target type. Interceptors will be determined /// via Intercept attributes on the class or added with InterceptedBy(). @@ -56,6 +78,30 @@ public static IRegistrationBuilder + /// Enable class interception on the target type, conditionally based on the + /// implementation type. Interceptors will be determined via Intercept attributes + /// on the class or added with InterceptedBy(). Only virtual methods can be + /// intercepted this way. + /// + /// Registration limit type. + /// Activator data type. + /// Registration style. + /// Registration to apply interception to. + /// + /// A predicate, evaluated against the implementation type, that determines + /// whether interception is applied. When the predicate returns + /// the type is registered without interception. + /// + /// Registration builder allowing the registration to be configured. + public static IRegistrationBuilder EnableClassInterceptors( + this IRegistrationBuilder registration, + Func shouldIntercept) + where TConcreteReflectionActivatorData : ConcreteReflectionActivatorData + { + return EnableClassInterceptors(registration, ProxyGenerationOptions.Default, shouldIntercept); + } + /// /// Enable class interception on the target type. Interceptors will be determined /// via Intercept attributes on the class or added with InterceptedBy(). @@ -71,13 +117,39 @@ public static IRegistrationBuilder registration, ProxyGenerationOptions options, params Type[] additionalInterfaces) + { + return EnableClassInterceptors(registration, options, null, additionalInterfaces); + } + + /// + /// Enable class interception on the target type. Interceptors will be determined + /// via Intercept attributes on the class or added with InterceptedBy(). + /// Only virtual methods can be intercepted this way. + /// + /// Registration limit type. + /// Registration style. + /// Registration to apply interception to. + /// Proxy generation options to apply. + /// + /// An optional predicate, evaluated against each candidate implementation type, + /// that determines whether interception is applied. Types for which the predicate + /// returns are registered without interception. When + /// all types are intercepted. + /// + /// Additional interface types. Calls to their members will be proxied as well. + /// Registration builder allowing the registration to be configured. + public static IRegistrationBuilder EnableClassInterceptors( + this IRegistrationBuilder registration, + ProxyGenerationOptions options, + Func? shouldIntercept, + params Type[] additionalInterfaces) { if (registration == null) { throw new ArgumentNullException(nameof(registration)); } - registration.ActivatorData.ConfigurationActions.Add((t, rb) => rb.EnableClassInterceptors(options, additionalInterfaces)); + registration.ActivatorData.ConfigurationActions.Add((t, rb) => rb.EnableClassInterceptors(options, shouldIntercept, additionalInterfaces)); return registration; } @@ -98,12 +170,48 @@ public static IRegistrationBuilder + /// Enable class interception on the target type. Interceptors will be determined + /// via Intercept attributes on the class or added with InterceptedBy(). + /// Only virtual methods can be intercepted this way. + /// + /// Registration limit type. + /// Activator data type. + /// Registration style. + /// Registration to apply interception to. + /// Proxy generation options to apply. + /// + /// An optional predicate, evaluated against the implementation type, that + /// determines whether interception is applied. When the predicate returns + /// the type is registered without interception. When + /// the type is intercepted. + /// + /// Additional interface types. Calls to their members will be proxied as well. + /// Registration builder allowing the registration to be configured. + public static IRegistrationBuilder EnableClassInterceptors( + this IRegistrationBuilder registration, + ProxyGenerationOptions options, + Func? shouldIntercept, + params Type[] additionalInterfaces) + where TConcreteReflectionActivatorData : ConcreteReflectionActivatorData { if (registration == null) { throw new ArgumentNullException(nameof(registration)); } + // Class interception rewrites the implementation type to a proxy subclass + // at registration time, so the decision to intercept is made here, per type. + // When the predicate rejects the type the registration is left untouched. + if (shouldIntercept != null && !shouldIntercept(registration.ActivatorData.ImplementationType)) + { + return registration; + } + registration.ActivatorData.ImplementationType = _proxyGenerator.ProxyBuilder.CreateClassProxyType( registration.ActivatorData.ImplementationType, @@ -154,6 +262,52 @@ public static IRegistrationBuilderRegistration builder allowing the registration to be configured. public static IRegistrationBuilder EnableInterfaceInterceptors( this IRegistrationBuilder registration, ProxyGenerationOptions? options = null) + { + return EnableInterfaceInterceptors(registration, options, null); + } + + /// + /// Enable interface interception on the target type, conditionally based on the + /// resolved implementation type. Interceptors will be determined via Intercept + /// attributes on the class or interface, or added with InterceptedBy() calls. + /// + /// Registration limit type. + /// Activator data type. + /// Registration style. + /// Registration to apply interception to. + /// + /// A predicate, evaluated against the resolved implementation type, that + /// determines whether interception is applied. When the predicate returns + /// the resolved instance is returned without a proxy. + /// + /// Registration builder allowing the registration to be configured. + public static IRegistrationBuilder EnableInterfaceInterceptors( + this IRegistrationBuilder registration, + Func shouldIntercept) + { + return EnableInterfaceInterceptors(registration, null, shouldIntercept); + } + + /// + /// Enable interface interception on the target type, conditionally based on the + /// resolved implementation type. Interceptors will be determined via Intercept + /// attributes on the class or interface, or added with InterceptedBy() calls. + /// + /// Registration limit type. + /// Activator data type. + /// Registration style. + /// Registration to apply interception to. + /// Proxy generation options to apply. + /// + /// A predicate, evaluated against the resolved implementation type, that + /// determines whether interception is applied. When the predicate returns + /// the resolved instance is returned without a proxy. + /// + /// Registration builder allowing the registration to be configured. + public static IRegistrationBuilder EnableInterfaceInterceptors( + this IRegistrationBuilder registration, + ProxyGenerationOptions? options, + Func? shouldIntercept) { if (registration == null) { @@ -164,11 +318,21 @@ public static IRegistrationBuilder ctx.ResolveService(s)) .Cast() .ToArray(); diff --git a/test/Autofac.Extras.DynamicProxy.Test/ConditionalInterceptionFixture.cs b/test/Autofac.Extras.DynamicProxy.Test/ConditionalInterceptionFixture.cs new file mode 100644 index 0000000..acfed34 --- /dev/null +++ b/test/Autofac.Extras.DynamicProxy.Test/ConditionalInterceptionFixture.cs @@ -0,0 +1,177 @@ +// Copyright (c) Autofac Project. All rights reserved. +// Licensed under the MIT License. See LICENSE in the project root for license information. + +using Autofac.Builder; +using Autofac.Features.Scanning; +using Castle.DynamicProxy; +using IInvocation = Castle.DynamicProxy.IInvocation; + +namespace Autofac.Extras.DynamicProxy.Test; + +public class ConditionalInterceptionFixture +{ + [Fact] + public void NullRegistration_Throws() + { + IRegistrationBuilder concrete = null!; + IRegistrationBuilder scanning = null!; + Func predicate = _ => true; + + Assert.Throws(() => concrete.EnableInterfaceInterceptors(predicate)); + Assert.Throws(() => concrete.EnableClassInterceptors(predicate)); + Assert.Throws(() => scanning.EnableClassInterceptors(predicate)); + } + + [AttributeUsage(AttributeTargets.Class)] + private sealed class InterceptMeAttribute : Attribute + { + } + + public interface IPublicInterface + { + string PublicMethod(); + } + + [Fact] + public void InterfaceInterception_AppliesProxyWhenPredicateMatches() + { + var builder = new ContainerBuilder(); + builder.RegisterType(); + builder + .RegisterType() + .EnableInterfaceInterceptors(t => t.IsDefined(typeof(InterceptMeAttribute), false)) + .InterceptedBy(typeof(StringMethodInterceptor)) + .As(); + var container = builder.Build(); + + var obj = container.Resolve(); + + Assert.Equal("intercepted-PublicMethod", obj.PublicMethod()); + } + + [Fact] + public void InterfaceInterception_SkipsProxyWhenPredicateDoesNotMatch() + { + var builder = new ContainerBuilder(); + builder.RegisterType(); + builder + .RegisterType() + .EnableInterfaceInterceptors(t => t.IsDefined(typeof(InterceptMeAttribute), false)) + .InterceptedBy(typeof(StringMethodInterceptor)) + .As(); + var container = builder.Build(); + + var obj = container.Resolve(); + + // Predicate returns false, so the raw instance is returned without a proxy. + Assert.Equal("PublicMethod", obj.PublicMethod()); + Assert.IsType(obj); + } + + [Fact] + public void InterfaceInterception_PredicateAppliesPerScannedType() + { + var builder = new ContainerBuilder(); + builder.RegisterType(); + builder + .RegisterAssemblyTypes(typeof(ConditionalInterceptionFixture).Assembly) + .Where(t => t == typeof(Intercepted) || t == typeof(NotIntercepted)) + .As() + .EnableInterfaceInterceptors(t => t.IsDefined(typeof(InterceptMeAttribute), false)) + .InterceptedBy(typeof(StringMethodInterceptor)); + var container = builder.Build(); + + var all = container.Resolve>().ToList(); + + // The attributed type is proxied; the other is returned untouched. + Assert.Contains(all, o => o.PublicMethod() == "intercepted-PublicMethod"); + Assert.Contains(all, o => o.PublicMethod() == "PublicMethod"); + } + + [Fact] + public void ClassInterception_AppliesProxyWhenPredicateMatches() + { + var builder = new ContainerBuilder(); + builder.RegisterType(); + builder + .RegisterType() + .EnableClassInterceptors(t => t.IsDefined(typeof(InterceptMeAttribute), false)) + .InterceptedBy(typeof(StringMethodInterceptor)); + var container = builder.Build(); + + var obj = container.Resolve(); + + Assert.Equal("intercepted-VirtualMethod", obj.VirtualMethod()); + } + + [Fact] + public void ClassInterception_SkipsProxyWhenPredicateDoesNotMatch() + { + var builder = new ContainerBuilder(); + builder.RegisterType(); + builder + .RegisterType() + .EnableClassInterceptors(t => t.IsDefined(typeof(InterceptMeAttribute), false)) + .InterceptedBy(typeof(StringMethodInterceptor)); + var container = builder.Build(); + + var obj = container.Resolve(); + + // Predicate returns false, so the type is registered without a proxy. + Assert.Equal("VirtualMethod", obj.VirtualMethod()); + Assert.Same(typeof(NotInterceptedClass), obj.GetType()); + } + + [Fact] + public void ClassInterception_PredicateAppliesPerScannedType() + { + var builder = new ContainerBuilder(); + builder.RegisterType(); + builder + .RegisterAssemblyTypes(typeof(ConditionalInterceptionFixture).Assembly) + .Where(t => t == typeof(InterceptedClass) || t == typeof(NotInterceptedClass)) + .EnableClassInterceptors(t => t.IsDefined(typeof(InterceptMeAttribute), false)) + .InterceptedBy(typeof(StringMethodInterceptor)); + var container = builder.Build(); + + Assert.Equal("intercepted-VirtualMethod", container.Resolve().VirtualMethod()); + Assert.Equal("VirtualMethod", container.Resolve().VirtualMethod()); + } + + [InterceptMe] + public class Intercepted : IPublicInterface + { + public string PublicMethod() => "PublicMethod"; + } + + public class NotIntercepted : IPublicInterface + { + public string PublicMethod() => "PublicMethod"; + } + + [InterceptMe] + public class InterceptedClass + { + public virtual string VirtualMethod() => "VirtualMethod"; + } + + public class NotInterceptedClass + { + public virtual string VirtualMethod() => "VirtualMethod"; + } + + private class StringMethodInterceptor : IInterceptor + { + public void Intercept(IInvocation invocation) + { + if (invocation.Method.ReturnType == typeof(string)) + { + invocation.ReturnValue = "intercepted-" + invocation.Method.Name; + } + else + { + invocation.Proceed(); + } + } + } +} From a6fd59116912b893a62282c4ebd5c9273d347233 Mon Sep 17 00:00:00 2001 From: Travis Illig Date: Wed, 24 Jun 2026 07:22:01 -0700 Subject: [PATCH 2/2] Updated documentation. --- .../RegistrationExtensions.cs | 398 +++++++++++++----- 1 file changed, 288 insertions(+), 110 deletions(-) diff --git a/src/Autofac.Extras.DynamicProxy/RegistrationExtensions.cs b/src/Autofac.Extras.DynamicProxy/RegistrationExtensions.cs index eb338da..966f875 100644 --- a/src/Autofac.Extras.DynamicProxy/RegistrationExtensions.cs +++ b/src/Autofac.Extras.DynamicProxy/RegistrationExtensions.cs @@ -25,14 +25,24 @@ public static class RegistrationExtensions private static readonly ProxyGenerator _proxyGenerator = new(); /// - /// Enable class interception on the target type. Interceptors will be determined - /// via Intercept attributes on the class or added with InterceptedBy(). + /// Enable class interception on the target type. Interceptors will be + /// determined via on the class or added + /// with + /// . /// Only virtual methods can be intercepted this way. /// - /// Registration limit type. - /// Registration style. - /// Registration to apply interception to. - /// Registration builder allowing the registration to be configured. + /// + /// Registration limit type. + /// + /// + /// Registration style. + /// + /// + /// Registration to apply interception to. + /// + /// + /// Registration builder allowing the registration to be configured. + /// public static IRegistrationBuilder EnableClassInterceptors( this IRegistrationBuilder registration) { @@ -41,19 +51,29 @@ public static IRegistrationBuilder /// Enable class interception on the target type, conditionally based on the - /// implementation type. Interceptors will be determined via Intercept attributes - /// on the class or added with InterceptedBy(). Only virtual methods can be - /// intercepted this way. + /// implementation type. Interceptors will be determined via + /// on the class or added with + /// . + /// Only virtual methods can be intercepted this way. /// - /// Registration limit type. - /// Registration style. - /// Registration to apply interception to. + /// + /// Registration limit type. + /// + /// + /// Registration style. + /// + /// + /// Registration to apply interception to. + /// /// /// A predicate, evaluated against each candidate implementation type, that - /// determines whether interception is applied. Types for which the predicate - /// returns are registered without interception. + /// determines whether interception is applied. Types for which the + /// predicate returns are registered without + /// interception. /// - /// Registration builder allowing the registration to be configured. + /// + /// Registration builder allowing the registration to be configured. + /// public static IRegistrationBuilder EnableClassInterceptors( this IRegistrationBuilder registration, Func shouldIntercept) @@ -62,15 +82,27 @@ public static IRegistrationBuilder - /// Enable class interception on the target type. Interceptors will be determined - /// via Intercept attributes on the class or added with InterceptedBy(). + /// Enable class interception on the target type. Interceptors will be + /// determined via on the class or added + /// with + /// . /// Only virtual methods can be intercepted this way. /// - /// Registration limit type. - /// Activator data type. - /// Registration style. - /// Registration to apply interception to. - /// Registration builder allowing the registration to be configured. + /// + /// Registration limit type. + /// + /// + /// Activator data type. + /// + /// + /// Registration style. + /// + /// + /// Registration to apply interception to. + /// + /// + /// Registration builder allowing the registration to be configured. + /// public static IRegistrationBuilder EnableClassInterceptors( this IRegistrationBuilder registration) where TConcreteReflectionActivatorData : ConcreteReflectionActivatorData @@ -80,20 +112,31 @@ public static IRegistrationBuilder /// Enable class interception on the target type, conditionally based on the - /// implementation type. Interceptors will be determined via Intercept attributes - /// on the class or added with InterceptedBy(). Only virtual methods can be - /// intercepted this way. + /// implementation type. Interceptors will be determined via + /// on the class or added with + /// . + /// Only virtual methods can be intercepted this way. /// - /// Registration limit type. - /// Activator data type. - /// Registration style. - /// Registration to apply interception to. + /// + /// Registration limit type. + /// + /// + /// Activator data type. + /// + /// + /// Registration style. + /// + /// + /// Registration to apply interception to. + /// /// /// A predicate, evaluated against the implementation type, that determines /// whether interception is applied. When the predicate returns /// the type is registered without interception. /// - /// Registration builder allowing the registration to be configured. + /// + /// Registration builder allowing the registration to be configured. + /// public static IRegistrationBuilder EnableClassInterceptors( this IRegistrationBuilder registration, Func shouldIntercept) @@ -103,16 +146,30 @@ public static IRegistrationBuilder - /// Enable class interception on the target type. Interceptors will be determined - /// via Intercept attributes on the class or added with InterceptedBy(). + /// Enable class interception on the target type with specific options and + /// additional interfaces. Interceptors will be determined via + /// on the class or added with + /// . /// Only virtual methods can be intercepted this way. /// - /// Registration limit type. - /// Registration style. - /// Registration to apply interception to. - /// Proxy generation options to apply. - /// Additional interface types. Calls to their members will be proxied as well. - /// Registration builder allowing the registration to be configured. + /// + /// Registration limit type. + /// + /// + /// Registration style. + /// + /// + /// Registration to apply interception to. + /// + /// + /// Proxy generation options to apply. + /// + /// + /// Additional interface types. Calls to their members will be proxied as well. + /// + /// + /// Registration builder allowing the registration to be configured. + /// public static IRegistrationBuilder EnableClassInterceptors( this IRegistrationBuilder registration, ProxyGenerationOptions options, @@ -122,14 +179,25 @@ public static IRegistrationBuilder - /// Enable class interception on the target type. Interceptors will be determined - /// via Intercept attributes on the class or added with InterceptedBy(). + /// Enable class interception on the target type, conditionally based on the + /// implementation type, with specific options and additional interfaces. + /// Interceptors will be determined via on + /// the class or added with + /// . /// Only virtual methods can be intercepted this way. /// - /// Registration limit type. - /// Registration style. - /// Registration to apply interception to. - /// Proxy generation options to apply. + /// + /// Registration limit type. + /// + /// + /// Registration style. + /// + /// + /// Registration to apply interception to. + /// + /// + /// Proxy generation options to apply. + /// /// /// An optional predicate, evaluated against each candidate implementation type, /// that determines whether interception is applied. Types for which the predicate @@ -154,16 +222,30 @@ public static IRegistrationBuilder - /// Enable class interception on the target type. Interceptors will be determined - /// via Intercept attributes on the class or added with InterceptedBy(). + /// Enable class interception on the target type with specific options and + /// additional interfaces. Interceptors will be determined via + /// on the class or added with + /// . /// Only virtual methods can be intercepted this way. /// - /// Registration limit type. - /// Activator data type. - /// Registration style. - /// Registration to apply interception to. - /// Proxy generation options to apply. - /// Additional interface types. Calls to their members will be proxied as well. + /// + /// Registration limit type. + /// + /// + /// Activator data type. + /// + /// + /// Registration style. + /// + /// + /// Registration to apply interception to. + /// + /// + /// Proxy generation options to apply. + /// + /// + /// Additional interface types. Calls to their members will be proxied as well. + /// /// Registration builder allowing the registration to be configured. public static IRegistrationBuilder EnableClassInterceptors( this IRegistrationBuilder registration, @@ -175,23 +257,40 @@ public static IRegistrationBuilder - /// Enable class interception on the target type. Interceptors will be determined - /// via Intercept attributes on the class or added with InterceptedBy(). + /// Enable class interception on the target type, conditionally based on the + /// implementation type, with specific options and additional interfaces. + /// Interceptors will be determined via on + /// the class or added with + /// . /// Only virtual methods can be intercepted this way. /// - /// Registration limit type. - /// Activator data type. - /// Registration style. - /// Registration to apply interception to. - /// Proxy generation options to apply. + /// + /// Registration limit type. + /// + /// + /// Activator data type. + /// + /// + /// Registration style. + /// + /// + /// Registration to apply interception to. + /// + /// + /// Proxy generation options to apply. + /// /// /// An optional predicate, evaluated against the implementation type, that /// determines whether interception is applied. When the predicate returns /// the type is registered without interception. When /// the type is intercepted. /// - /// Additional interface types. Calls to their members will be proxied as well. - /// Registration builder allowing the registration to be configured. + /// + /// Additional interface types. Calls to their members will be proxied as well. + /// + /// + /// Registration builder allowing the registration to be configured. + /// public static IRegistrationBuilder EnableClassInterceptors( this IRegistrationBuilder registration, ProxyGenerationOptions options, @@ -251,15 +350,29 @@ public static IRegistrationBuilder - /// Enable interface interception on the target type. Interceptors will be determined - /// via Intercept attributes on the class or interface, or added with InterceptedBy() calls. + /// Enable interface interception on the target type. Interceptors will be + /// determined via on the class or + /// interface, or added with + /// . /// - /// Registration limit type. - /// Activator data type. - /// Registration style. - /// Registration to apply interception to. - /// Proxy generation options to apply. - /// Registration builder allowing the registration to be configured. + /// + /// Registration limit type. + /// + /// + /// Activator data type. + /// + /// + /// Registration style. + /// + /// + /// Registration to apply interception to. + /// + /// + /// Proxy generation options to apply. + /// + /// + /// Registration builder allowing the registration to be configured. + /// public static IRegistrationBuilder EnableInterfaceInterceptors( this IRegistrationBuilder registration, ProxyGenerationOptions? options = null) { @@ -267,20 +380,28 @@ public static IRegistrationBuilder - /// Enable interface interception on the target type, conditionally based on the - /// resolved implementation type. Interceptors will be determined via Intercept - /// attributes on the class or interface, or added with InterceptedBy() calls. + /// Enable interface interception on the target type, conditionally based on + /// the resolved implementation type. Interceptors will be determined via + /// on the class or interface, or added with + /// . /// - /// Registration limit type. - /// Activator data type. - /// Registration style. - /// Registration to apply interception to. + /// + /// Registration limit type. + /// + /// Activator data type. + /// + /// Registration style. + /// + /// Registration to apply interception to. + /// /// /// A predicate, evaluated against the resolved implementation type, that /// determines whether interception is applied. When the predicate returns /// the resolved instance is returned without a proxy. /// - /// Registration builder allowing the registration to be configured. + /// + /// Registration builder allowing the registration to be configured. + /// public static IRegistrationBuilder EnableInterfaceInterceptors( this IRegistrationBuilder registration, Func shouldIntercept) @@ -289,21 +410,35 @@ public static IRegistrationBuilder - /// Enable interface interception on the target type, conditionally based on the - /// resolved implementation type. Interceptors will be determined via Intercept - /// attributes on the class or interface, or added with InterceptedBy() calls. + /// Enable interface interception on the target type, conditionally based on + /// the resolved implementation type, with specific options. Interceptors + /// will be determined via on the class or + /// interface, or added with + /// . /// - /// Registration limit type. - /// Activator data type. - /// Registration style. - /// Registration to apply interception to. - /// Proxy generation options to apply. + /// + /// Registration limit type. + /// + /// + /// Activator data type. + /// + /// + /// Registration style. + /// + /// + /// Registration to apply interception to. + /// + /// + /// Proxy generation options to apply. + /// /// /// A predicate, evaluated against the resolved implementation type, that /// determines whether interception is applied. When the predicate returns /// the resolved instance is returned without a proxy. /// - /// Registration builder allowing the registration to be configured. + /// + /// Registration builder allowing the registration to be configured. + /// public static IRegistrationBuilder EnableInterfaceInterceptors( this IRegistrationBuilder registration, ProxyGenerationOptions? options, @@ -359,15 +494,29 @@ public static IRegistrationBuilder - /// Allows a list of interceptor services to be assigned to the registration. + /// Assigns a list of interceptor services to a registration by service. /// - /// Registration limit type. - /// Activator data type. - /// Registration style. - /// Registration to apply interception to. - /// The interceptor services. - /// Registration builder allowing the registration to be configured. - /// or . + /// + /// Registration limit type. + /// + /// + /// Activator data type. + /// + /// + /// Registration style. + /// + /// + /// Registration to apply interception to. + /// + /// + /// The interceptor services. + /// + /// + /// Registration builder allowing the registration to be configured. + /// + /// + /// Thrown when or is . + /// public static IRegistrationBuilder InterceptedBy( this IRegistrationBuilder builder, params Service[] interceptorServices) @@ -388,15 +537,29 @@ public static IRegistrationBuilder InterceptedBy } /// - /// Allows a list of interceptor services to be assigned to the registration. + /// Assigns a list of interceptor services to a registration by name. /// - /// Registration limit type. - /// Activator data type. - /// Registration style. - /// Registration to apply interception to. - /// The names of the interceptor services. - /// Registration builder allowing the registration to be configured. - /// or . + /// + /// Registration limit type. + /// + /// + /// Activator data type. + /// + /// + /// Registration style. + /// + /// + /// Registration to apply interception to. + /// + /// + /// The names of the interceptor services. + /// + /// + /// Registration builder allowing the registration to be configured. + /// + /// + /// Thrown when or is . + /// public static IRegistrationBuilder InterceptedBy( this IRegistrationBuilder builder, params string[] interceptorServiceNames) @@ -410,15 +573,30 @@ public static IRegistrationBuilder InterceptedBy } /// - /// Allows a list of interceptor services to be assigned to the registration. + /// Assigns a list of interceptor services to a registration by interceptor + /// type. /// - /// Registration limit type. - /// Activator data type. - /// Registration style. - /// Registration to apply interception to. - /// The types of the interceptor services. - /// Registration builder allowing the registration to be configured. - /// or . + /// + /// Registration limit type. + /// + /// + /// Activator data type. + /// + /// + /// Registration style. + /// + /// + /// Registration to apply interception to. + /// + /// + /// The types of the interceptor services. + /// + /// + /// Registration builder allowing the registration to be configured. + /// + /// + /// Thrown when or is . + /// public static IRegistrationBuilder InterceptedBy( this IRegistrationBuilder builder, params Type[] interceptorServiceTypes)