From 7eb22b3cc0ccec54c59abf68fce3a426f1a91466 Mon Sep 17 00:00:00 2001 From: Fabio Salvalai Date: Thu, 17 May 2018 16:13:10 +0200 Subject: [PATCH 1/2] Implement filtering on types ancestors, and arbitrary Func. --- .../Autofac.BindingByConvention.csproj | 2 +- .../FluentSyntax/FluentExceptInterfaces.cs | 66 ++++++++++++++++--- .../FluentSyntax/IFluentExceptInterfaces.cs | 3 + 3 files changed, 62 insertions(+), 9 deletions(-) diff --git a/src/Autofac.BindingByConvention/Autofac.BindingByConvention.csproj b/src/Autofac.BindingByConvention/Autofac.BindingByConvention.csproj index c8f2588..cfce6c3 100644 --- a/src/Autofac.BindingByConvention/Autofac.BindingByConvention.csproj +++ b/src/Autofac.BindingByConvention/Autofac.BindingByConvention.csproj @@ -16,7 +16,7 @@ en false true - 0.0.3 + 0.0.5 $(AssemblyVersion) $(AssemblyVersion) diff --git a/src/Autofac.BindingByConvention/FluentSyntax/FluentExceptInterfaces.cs b/src/Autofac.BindingByConvention/FluentSyntax/FluentExceptInterfaces.cs index 0721e38..5464087 100644 --- a/src/Autofac.BindingByConvention/FluentSyntax/FluentExceptInterfaces.cs +++ b/src/Autofac.BindingByConvention/FluentSyntax/FluentExceptInterfaces.cs @@ -9,38 +9,88 @@ public class FluentExceptInterfaces : IFluentExceptInterfaces { private readonly FluentContractFilter fluentContractFilter; - private readonly List> filters; + /// + /// The conditions to fulfill for a type not to be excluded. + /// + private readonly List> conditionsToFulfill; /// public FluentExceptInterfaces(FluentContractFilter fluentContractFilter, params Func[] predicates) { this.fluentContractFilter = fluentContractFilter; - this.filters = new List>(predicates); + this.conditionsToFulfill = new List>(predicates); } /// public FluentContractFilter Types(IEnumerable contractsToIgnore) { - this.filters.Add((interfaceType, implementationType) => !contractsToIgnore.Contains(interfaceType)); + this.conditionsToFulfill.Add((interfaceType, implementationType) => !contractsToIgnore.Contains(interfaceType)); return this.fluentContractFilter; } /// public FluentContractFilter ContractsMarkedWith() where T : Attribute { - this.filters.Add((interfaceType, implementationType) => !interfaceType.IsDefined(typeof(T), false)); + this.conditionsToFulfill.Add((interfaceType, implementationType) => !interfaceType.IsDefined(typeof(T), false)); + return this.fluentContractFilter; + } + + public FluentContractFilter InheritsFrom() + { + this.conditionsToFulfill.Add((interfaceType, implementationType) => !this.InheritsFromInternal(implementationType, typeof(TAncestor))); + return this.fluentContractFilter; + } + + public FluentContractFilter TypesMatching(Func predicate) + { + this.conditionsToFulfill.Add(predicate); return this.fluentContractFilter; } + private bool InheritsFromInternal(Type type, Type baseType) + { + // null does not have base type + if (type == null) + { + return false; + } + + // only interface can have null base type + if (baseType == null) + { + return type.IsInterface; + } + + // check implemented interfaces + if (baseType.IsInterface) + { + return type.GetInterfaces().Contains(baseType); + } + + // check all base types + var currentType = type; + while (currentType != null) + { + if (currentType.BaseType == baseType) + { + return true; + } + + currentType = currentType.BaseType; + } + + return false; + } + /// - /// Checks that all filters are satisfied. + /// Checks that all conditionsToFulfill are satisfied. /// /// Type of the interface. /// Type of the implementation. - /// True if all defined filters are satisfied; False otherwise. + /// True if all defined conditionsToFulfill are satisfied; False otherwise. public bool CheckAllFiltersSatisfied(Type interfaceType, Type implementationType) - { - return this.filters.All(filter => filter(interfaceType, implementationType)); + { + return this.conditionsToFulfill.All(filter => filter(interfaceType, implementationType)); } } } \ No newline at end of file diff --git a/src/Autofac.BindingByConvention/FluentSyntax/IFluentExceptInterfaces.cs b/src/Autofac.BindingByConvention/FluentSyntax/IFluentExceptInterfaces.cs index d3445d1..f4ea141 100644 --- a/src/Autofac.BindingByConvention/FluentSyntax/IFluentExceptInterfaces.cs +++ b/src/Autofac.BindingByConvention/FluentSyntax/IFluentExceptInterfaces.cs @@ -23,5 +23,8 @@ public interface IFluentExceptInterfaces /// The attribute that marks interface types that must be ignored by the described convention. For instance, /// The fluent connector for a proper fluent syntax. FluentContractFilter ContractsMarkedWith() where TAttribute : Attribute; + + FluentContractFilter InheritsFrom(); + FluentContractFilter TypesMatching(Func predicate); } } \ No newline at end of file From 01a9149d874827c22aa9c74ec1f8f7e612c25fe9 Mon Sep 17 00:00:00 2001 From: Fabio Salvalai Date: Fri, 18 May 2018 09:27:44 +0200 Subject: [PATCH 2/2] Add doc --- .../FluentSyntax/IFluentExceptInterfaces.cs | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/src/Autofac.BindingByConvention/FluentSyntax/IFluentExceptInterfaces.cs b/src/Autofac.BindingByConvention/FluentSyntax/IFluentExceptInterfaces.cs index f4ea141..d63a561 100644 --- a/src/Autofac.BindingByConvention/FluentSyntax/IFluentExceptInterfaces.cs +++ b/src/Autofac.BindingByConvention/FluentSyntax/IFluentExceptInterfaces.cs @@ -11,20 +11,31 @@ namespace Autofac.BindingByConvention.FluentSyntax public interface IFluentExceptInterfaces { /// - /// Ignores the interface types if they are contained in the specified . + /// Exclude the types from the binding convention if they are contained in the specified . /// /// The interface types to ignore. /// The fluent connector for a proper fluent syntax. FluentContractFilter Types(IEnumerable contractsToIgnore); /// - /// Ignores the interface types if they are decorated with the specified attribute . + /// Exclude the types from the binding convention if they are decorated with the specified attribute . /// /// The attribute that marks interface types that must be ignored by the described convention. For instance, /// The fluent connector for a proper fluent syntax. FluentContractFilter ContractsMarkedWith() where TAttribute : Attribute; + /// + /// Exclude the types from the binding convention if they inherit from the specified ancestor . + /// + /// The type of the ancestor; all classes inheriting from it will be ignored. + /// The fluent connector for a proper fluent syntax. FluentContractFilter InheritsFrom(); + + /// + /// Exclude the types from the binding convention if they match the specified . + /// + /// The predicate; all classes matching it will be ignored. + /// The fluent connector for a proper fluent syntax. FluentContractFilter TypesMatching(Func predicate); } } \ No newline at end of file