Skip to content

Commit

Permalink
Merge pull request #3 from VaudoiseAssurances/feature/2-InheritsFrom
Browse files Browse the repository at this point in the history
Feature/2 inherits from
  • Loading branch information
salfab authored May 20, 2018
2 parents d985c7f + 01a9149 commit e479b8e
Show file tree
Hide file tree
Showing 3 changed files with 75 additions and 11 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
<NeutralLanguage>en</NeutralLanguage>
<PackageRequireLicenseAcceptance>false</PackageRequireLicenseAcceptance>
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
<AssemblyVersion>0.0.3</AssemblyVersion>
<AssemblyVersion>0.0.5</AssemblyVersion>
<VersionPrefix>$(AssemblyVersion)</VersionPrefix>
<FileVersion>$(AssemblyVersion)</FileVersion>
</PropertyGroup>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,38 +9,88 @@ public class FluentExceptInterfaces : IFluentExceptInterfaces
{
private readonly FluentContractFilter fluentContractFilter;

private readonly List<Func<Type, Type, bool>> filters;
/// <summary>
/// The conditions to fulfill for a type not to be excluded.
/// </summary>
private readonly List<Func<Type, Type, bool>> conditionsToFulfill;

/// <inheritdoc />
public FluentExceptInterfaces(FluentContractFilter fluentContractFilter, params Func<Type, Type, bool>[] predicates)
{
this.fluentContractFilter = fluentContractFilter;
this.filters = new List<Func<Type, Type, bool>>(predicates);
this.conditionsToFulfill = new List<Func<Type, Type, bool>>(predicates);
}

/// <inheritdoc />
public FluentContractFilter Types(IEnumerable<Type> contractsToIgnore)
{
this.filters.Add((interfaceType, implementationType) => !contractsToIgnore.Contains(interfaceType));
this.conditionsToFulfill.Add((interfaceType, implementationType) => !contractsToIgnore.Contains(interfaceType));
return this.fluentContractFilter;
}

/// <inheritdoc />
public FluentContractFilter ContractsMarkedWith<T>() 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<TAncestor>()
{
this.conditionsToFulfill.Add((interfaceType, implementationType) => !this.InheritsFromInternal(implementationType, typeof(TAncestor)));
return this.fluentContractFilter;
}

public FluentContractFilter TypesMatching(Func<Type, Type, bool> 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;
}

/// <summary>
/// Checks that all filters are satisfied.
/// Checks that all conditionsToFulfill are satisfied.
/// </summary>
/// <param name="interfaceType">Type of the interface.</param>
/// <param name="implementationType">Type of the implementation.</param>
/// <returns><c>True</c> if all defined filters are satisfied; <c>False</c> otherwise.</returns>
/// <returns><c>True</c> if all defined conditionsToFulfill are satisfied; <c>False</c> otherwise.</returns>
public bool CheckAllFiltersSatisfied(Type interfaceType, Type implementationType)
{
return this.filters.All(filter => filter(interfaceType, implementationType));
{
return this.conditionsToFulfill.All(filter => filter(interfaceType, implementationType));
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,17 +11,31 @@ namespace Autofac.BindingByConvention.FluentSyntax
public interface IFluentExceptInterfaces
{
/// <summary>
/// Ignores the interface types if they are contained in the specified <paramref name="contractsToIgnore" />.
/// Exclude the types from the binding convention if they are contained in the specified <paramref name="contractsToIgnore" />.
/// </summary>
/// <param name="contractsToIgnore">The interface types to ignore.</param>
/// <returns>The fluent connector for a proper fluent syntax.</returns>
FluentContractFilter Types(IEnumerable<Type> contractsToIgnore);

/// <summary>
/// Ignores the interface types if they are decorated with the specified attribute <typeparamref name="TAttribute"/>.
/// Exclude the types from the binding convention if they are decorated with the specified attribute <typeparamref name="TAttribute"/>.
/// </summary>
/// <typeparam name="TAttribute">The attribute that marks interface types that must be ignored by the described convention. For instance, <see cref="NoBindingByConventionAttribute"/></typeparam>
/// <returns>The fluent connector for a proper fluent syntax.</returns>
FluentContractFilter ContractsMarkedWith<TAttribute>() where TAttribute : Attribute;

/// <summary>
/// Exclude the types from the binding convention if they inherit from the specified ancestor <typeparamref name="TAncestor"/>.
/// </summary>
/// <typeparam name="TAncestor">The type of the ancestor; all classes inheriting from it will be ignored.</typeparam>
/// <returns>The fluent connector for a proper fluent syntax.</returns>
FluentContractFilter InheritsFrom<TAncestor>();

/// <summary>
/// Exclude the types from the binding convention if they match the specified <paramref name="predicate"/>.
/// </summary>
/// <param name="predicate">The predicate; all classes matching it will be ignored.</param>
/// <returns>The fluent connector for a proper fluent syntax.</returns>
FluentContractFilter TypesMatching(Func<Type,Type,bool> predicate);
}
}

0 comments on commit e479b8e

Please sign in to comment.