Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature/2 inherits from #3

Merged
merged 2 commits into from
May 20, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

upgrade is needed ? Deployed NuGet is still at 0.0.1. and here we target the develop branch

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The develop branch should trigger a - BETAXX package publication

Copy link
Contributor Author

@salfab salfab May 20, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oooh I see what you mean!

Sorry. No, we would not have needed this. True! Sorry.

<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);
}
}