Code Monkey home page Code Monkey logo

archunitnet's People

Contributors

alexanderlinne avatar andredered avatar bazile avatar brandhuf avatar changethecode avatar fgather avatar fholger avatar francisgauthier1 avatar gbtb avatar georgkreuzmayr avatar grzegorzorwat avatar ivsavchenko avatar mak638 avatar nikolausm avatar paularuiz22 avatar paulroho avatar renovate-bot avatar renovate[bot] avatar rubbiroid avatar semuell avatar simonthum avatar studix avatar thomasdc avatar tristanjschoenmakers avatar zdi-stephanjoneleit avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

archunitnet's Issues

Analyse dependencies of async methods

Background

Create a class that has an async method which uses another class:

namespace SomeNamespace
{
    public class ClassWithAsyncMethod
    {
        public async void MethodAsync()
        {
            var otherClass = new OtherClass();
        }
    }

    public class OtherClass
    {
    }
}

Create a rule that verifies that ClassWithAsyncMethod does not depend on OtherClass:

[Fact]
public void Class_should_not_depend_on_other_class()
{
	var rule = Types().That().Are(typeof(ClassWithAsyncMethod)).
		Should().NotDependOnAny(Types().That().Are(typeof(OtherClass)));

	rule.Check(Architecture);
}

Expected result

Rule fails.

Actual result

Rule passes.

Reason

When using the async keyword the compiler creates a nested helper class that contains the logic of MethodAsync (the instantiation of OtherClass). MethodAsync itself contains just the logic to use the helper class. The analysis scans MethodAsync but not the nested helper class. So the dependency to OtherClass is not detected.

Solution

Extend analysis to scan the nested helper class also.

Assemblies should expose attributes

When the attributes are constructed their attributes are not collected.
Thus you can not determine if an assembly has a specific attribute.

Dependency Dashboard

This issue lists Renovate updates and detected dependencies. Read the Dependency Dashboard docs to learn more.

Open

These updates have all been created already. Click a checkbox below to force a retry/rebase of any.

Detected dependencies

github-actions
.github/workflows/build.yaml
  • actions/checkout v4.1.6@a5ac7e51b41094c92402da3b24376905380afc29
  • actions/setup-dotnet v4.0.0@4d6c8fcf3c8f7a60068d26b594648e99df24cee3
  • actions/checkout v4.1.6@a5ac7e51b41094c92402da3b24376905380afc29
  • actions/setup-dotnet v4.0.0@4d6c8fcf3c8f7a60068d26b594648e99df24cee3
  • codecov/codecov-action v4.4.1
  • actions/checkout v4.1.6@a5ac7e51b41094c92402da3b24376905380afc29
  • actions/setup-dotnet v4.0.0@4d6c8fcf3c8f7a60068d26b594648e99df24cee3
  • actions/checkout v4.1.6@a5ac7e51b41094c92402da3b24376905380afc29
  • actions/setup-dotnet v4.0.0@4d6c8fcf3c8f7a60068d26b594648e99df24cee3
.github/workflows/codeql.yml
  • actions/checkout v4.1.6@a5ac7e51b41094c92402da3b24376905380afc29
  • github/codeql-action v3.25.6@9fdb3e49720b44c48891d036bb502feb25684276
  • github/codeql-action v3.25.6@9fdb3e49720b44c48891d036bb502feb25684276
  • github/codeql-action v3.25.6@9fdb3e49720b44c48891d036bb502feb25684276
nuget
.config/dotnet-tools.json
  • csharpier 0.28.2
ArchUnitNET.MSTestV2/ArchUnitNET.MSTestV2.csproj
ArchUnitNET.MSTestV2Tests/ArchUnitNET.MSTestV2Tests.csproj
ArchUnitNET.NUnit/ArchUnitNET.NUnit.csproj
ArchUnitNET.NUnitTests/ArchUnitNET.NUnitTests.csproj
ArchUnitNET.xUnit/ArchUnitNET.xUnit.csproj
ArchUnitNET/ArchUnitNET.csproj
  • System.ValueTuple 4.5.0
  • Newtonsoft.Json 13.0.3
  • Mono.Cecil 0.11.5
  • CycleDetection 2.0.0
ArchUnitNETTests/ArchUnitNETTests.csproj
  • coverlet.collector 6.0.2
ExampleTest/ExampleTest.csproj
global.json
  • dotnet-sdk 8.0.300
regex
.github/workflows/build.yaml
  • dotnet-sdk 8.0.300
  • dotnet-sdk 8.0.300
  • dotnet-sdk 8.0.300
  • dotnet-sdk 8.0.300
ArchUnitNET.MSTestV2Tests/ArchUnitNET.MSTestV2Tests.csproj
  • dotnet-sdk 8.0
ArchUnitNET.NUnitTests/ArchUnitNET.NUnitTests.csproj
  • dotnet-sdk 8.0
ArchUnitNETTests/ArchUnitNETTests.csproj
  • dotnet-sdk 8.0
ExampleTest/ExampleTest.csproj
  • dotnet-sdk 8.0
TestAssembly/TestAssembly.csproj
  • dotnet-sdk 8.0

  • Check this box to trigger a request for Renovate to run again on this repository

installing ArchUnitNET.xUnit breaks xUnit

After installing ArchUnitNET.xUnit in an existing xUnit test project, existing tests fail to compile with error Error CS0433 The type 'Assert' exists in both 'ArchUnitNET.xUnit, Version=0.4.3.0, Culture=neutral, PublicKeyToken=null' and 'xunit.assert, Version=2.4.1.0, Culture=neutral, PublicKeyToken=8d05b1bb7a6fdb6c'.
The reason is that ArchUnitNET.xUnit defines a partial class XUnit.Assert, but the compiler doesn't support partial classes declared in different assemblies. The solution would be to rename XUnit.Assert to XUnit.ArchRuleAssert, as it is in ArchUnitNET.NUnit.

Action Required: Fix Renovate Configuration

There is an error with this repository's Renovate configuration that needs to be fixed. As a precaution, Renovate will stop PRs until it is resolved.

Error type: Cannot find preset's package (github>whitesource/merge-confidence:beta)

Better architecture

Now your package consists of one project. It is very difficult to understand dependencies in one project.
I suggest to split it on: Core, Internal/Infrastructure and Extensions/Utils. Core is main code. Internal is helpers. Extensions is utils and syntax sugar (Fluent).
Also I think it would be better to join Core and Domain namespaces to Reflection or Entities namespace. Now your Core is not true core. It's just domain loader.

This is just my opinion.

Dependency on external static classes is not recognized

Hi! Found an issue:

Classes().That().AreNot(allowedClasses)
     .Should().NotDependOnAny(typeof(JsonConvert))
     .Check(Architecture);

Throws an exception:

ArchUnitNET.Domain.Exceptions.TypeDoesNotExistInArchitecture : Type Newtonsoft.Json.JsonConvert does not exist in provided architecture or is no class...

JsonConvert contains static methods with are used in the code

Question: Load assemblies example

I have a question about you example for loading the assemblies.

Create a Test
private static readonly Architecture Architecture = new ArchLoader().LoadAssemblies(typeof(ExampleClass).Assembly, typeof(ForbiddenClass).Assembly) .Build();

You using a class instance to find the correct assembly to load it. This will assume that the class instance is in the correct assembly. From my point of view it could be that someone move this class and then the test isn't testing what it should.

From my point of view it would make more sense to use the System.Reflection.Assembly.Load("AssemblyName").
Advantages:

  • If assembly is renamed but test not adapt, test will failed.
    • System.IO.FileNotFoundException : Could not load file or assembly 'AssemblyName, Culture=neutral, PublicKeyToken=null'. The system cannot find the file specified.
  • Assembly loading is not depending on the class in case this is moving to other assembly

So now my question is there any reason which I didn't saw yet to use the class instances instead of loading the assembly by using the assembly name?

How to see what types you have captured?

Given a set of types, like this:

var domainLayer = ArchRuleDefinition.Types(true).That()
                .ResideInNamespace("MyDomain", true)
                .As("Domain Layer");

How can I debug and see what types are actually captured in this layer? for debugging my rules?

Check for immutability

There is currently no way to check if a class is (truly) immutable. The model allows to check whether there are no (visible) setters, but I would prefer to check whether fields are readonly/init-only. This is not exposed, but I think it should be.

.net reflection equivalent is FieldInfo.IsInitOnly.

I am unsure if/how cecil covers readonly.

Class.Type.Attributes is empty even when Attribute is applied

Consider the following test (using ArchUnitNET.xUnit):

using static ArchUnitNET.Fluent.ArchRuleDefinition;

public class ArchitectureTests
{
    [Obsolete]
    public class ObsoleteClass { }

    
    private static readonly  Architecture _architecture =
            new ArchLoader().LoadAssemblies(typeof(ArchitectureTests).Assembly).Build();

    private static readonly IObjectProvider<IType> _obsoleteClasses =
            Classes().That().Are(typeof(ObsoleteClass))
                .As("obsolete classes");


    [Fact(DisplayName = "should be true and is true")]
    public void ObsoleteClass_should_have_ObsoleteAttribute__by_HaveAnyAttributes()
    {
        var archRule = Classes().That()
            .Are(_obsoleteClasses)
            .Should().HaveAnyAttributes(typeof(ObsoleteAttribute));

        ArchRuleAssert.CheckRule(_architecture, archRule);
    }

    [Fact(DisplayName = "should be true, but is false")]
    public void ObsoleteClass_should_have_ObsoleteAttribute__by_FollowCustomCondition()
    {
        var archRule = Classes().That()
            .Are(_obsoleteClasses)
            .Should().FollowCustomCondition(
                @class => @class.Type.Attributes.Any(),
                "ObsoleteClass should have ObsoleteAttribute",
                "ObsoleteClass should have ObsoleteAttribute");

        ArchRuleAssert.CheckRule(_architecture, archRule);
    }
}

In version 0.5.0 running under .NET 5, the first test passes as expected - but the second one fails, since Class.Type.Attributes list is empty, even though it should contain ObsoleteAttribute.

TypeDoesNotExistInArchitecture: When using 'ImplementInterface'

Hi,

using the method ImplementInterface(...) throws a TypeDoesNotExistInArchitecture if no type was found in target architecture. If there is at least 1 type existing then that exception is not thrown.

ArchRuleDefinition.Classes()
    .That().ImplementInterface(typeof(IAnyInterface))
    .GetObjects(Architecture);

Curiously, if I use name matching then no exception is thrown:

ArchRuleDefinition.Classes()
    .That().HaveNameEndingWith("yyyyy")
    .GetObjects(Architecture);

Is that an expected behavior? I don't care if my users do not implement that interface, but if they do then I will have some rules for them.

Do you have coverage to .net 6??

I'm trying to use your lib in .net 6, but I changed the new model namespace and your lib didn't find. Do you have some solution for this?

image

ArchUnitNET itself has circular dependencies

ArchUnitNET itself has circular dependencies; shouldn't it be avoided? ;-)

Both tests failes

        public void WrittenWithoutCircularDependencies()
        {
            IArchRule noCycles = SliceRuleDefinition.Slices().Matching("ArchUnitNET.(*)").Should().BeFreeOfCycles();
            noCycles.Check(Architecture);
        }

        public void WrittenWithoutCircularDependencies2()
        {
            IArchRule noCycles = SliceRuleDefinition.Slices().Matching("ArchUnitNET.(**)").Should().BeFreeOfCycles();
            noCycles.Check(Architecture);
        }

BR Helmut

How to check that Fluent only depends on System, Core and Domain namespaces?

How to check that ArchUnitNET.Fluent only depends on System, ArchUnitNET.Core and ArchUnitNET.Domain namespaces? I wrote the test, but it fails.
Why your tests don't check your architecture? Or did I not found it?

    private static readonly Architecture Architecture = new ArchLoader().LoadAssemblies( typeof( Architecture ).Assembly ).Build();
    private static readonly IObjectProvider<IType> CoreLayer = ArchRuleDefinition.Types().That().ResideInNamespace( "ArchUnitNET.Core" ).As( "ArchUnitNET.Core" );
    private static readonly IObjectProvider<IType> DomainLayer = ArchRuleDefinition.Types().That().ResideInNamespace( "ArchUnitNET.Domain" ).As( "ArchUnitNET.Domain" );
    private static readonly IObjectProvider<IType> FluentLayer = ArchRuleDefinition.Types().That().ResideInNamespace( "ArchUnitNET.Fluent" ).As( "ArchUnitNET.Fluent" );

var rule1 = ArchRuleDefinition.Types()
    .That().Are( FluentLayer )
    .Should().DependOnAny( ArchRuleDefinition.Types().That().ResideInNamespace( "System" ).Or().ResideInNamespace( "ArchUnitNET.Core" ).Or().ResideInNamespace( "ArchUnitNET.Domain" ) );
ArchRuleAssert.FulfilsRule( Architecture, rule1 );

Message is hell ((

"Types that are ArchUnitNET.Fluent should depend on any Types that reside in namespace with full name containing "System" or reside in namespace with full name containing "ArchUnitNET.Core"..." failed:
    	ArchUnitNET.Fluent.ArchRuleDefinition does depend on System.Object and ArchUnitNET.Fluent.Syntax.Elements.Types.GivenTypes and ArchUnitNET.Fluent.Syntax.Elements.Types.Attributes.GivenAttributes and ArchUnitNET.Fluent.Syntax.Elements.Types.Classes.GivenClasses and ArchUnitNET.Fluent.Syntax.Elements.Types.Interfaces.GivenInterfaces and ArchUnitNET.Fluent.Syntax.Elements.Members.GivenMembers and ArchUnitNET.Fluent.Syntax.Elements.Members.FieldMembers.GivenFieldMembers and ArchUnitNET.Fluent.Syntax.Elements.Members.MethodMembers.GivenMethodMembers and ArchUnitNET.Fluent.Syntax.Elements.Members.PropertyMembers.GivenPropertyMembers
    	ArchUnitNET.Fluent.BasicObjectProviderDefinition does depend on System.Object and ArchUnitNET.Fluent.BasicObjectProvider`1<ArchUnitNET.Domain.IType> and ArchUnitNET.Fluent.BasicObjectProvider`1<ArchUnitNET.Domain.Attribute> and ArchUnitNET.Fluent.BasicObjectProvider`1<ArchUnitNET.Domain.Class> and ArchUnitNET.Fluent.BasicObjectProvider`1<ArchUnitNET.Domain.Interface> and ArchUnitNET.Fluent.BasicObjectProvider`1<ArchUnitNET.Domain.IMember> and ArchUnitNET.Fluent.BasicObjectProvider`1<ArchUnitNET.Domain.FieldMember> and ArchUnitNET.Fluent.BasicObjectProvider`1<ArchUnitNET.Domain.MethodMember> and ArchUnitNET.Fluent.BasicObjectProvider`1<ArchUnitNET.Domain.PropertyMember> and ArchUnitNET.Fluent.BasicObjectProviderDefinition+<>c
    	ArchUnitNET.Fluent.CombinedArchRuleDefinition does depend on System.Object and ArchUnitNET.Fluent.LogicalConjunction and ArchUnitNET.Fluent.ICanBeEvaluated and ArchUnitNET.Fluent.Syntax.Elements.Types.GivenTypes and ArchUnitNET.Fluent.Syntax.Elements.Types.Attributes.GivenAttributes and ArchUnitNET.Fluent.Syntax.Elements.Types.Classes.GivenClasses and ArchUnitNET.Fluent.Syntax.Elements.Types.Interfaces.GivenInterfaces and ArchUnitNET.Fluent.Syntax.Elements.Members.GivenMembers and ArchUnitNET.Fluent.Syntax.Elements.Members.FieldMembers.GivenFieldMembers and ArchUnitNET.Fluent.Syntax.Elements.Members.MethodMembers.GivenMethodMembers and ArchUnitNET.Fluent.Syntax.Elements.Members.PropertyMembers.GivenPropertyMembers
    	ArchUnitNET.Fluent.IArchRule does depend on ArchUnitNET.Fluent.ICanBeEvaluated and ArchUnitNET.Fluent.IHasDescription and ArchUnitNET.Fluent.CombinedArchRuleDefinition and ArchUnitNET.Fluent.IArchRule
    	ArchUnitNET.Fluent.IHasDescription does depend on System.String
    	ArchUnitNET.Fluent.LogicalConjunction does depend on System.Object and ArchUnitNET.Fluent.IHasDescription and System.Func`3<System.Boolean,System.Boolean,System.Boolean> and System.String and System.Runtime.CompilerServices.CompilerGeneratedAttribute and System.Boolean and ArchUnitNET.Fluent.LogicalConjunction and System.Int32
    	ArchUnitNET.Fluent.LogicalConjunctionDefinition does depend on System.Object and ArchUnitNET.Fluent.LogicalConjunction and ArchUnitNET.Fluent.LogicalConjunctionDefinition+AndConjunction and ArchUnitNET.Fluent.LogicalConjunctionDefinition+OrConjunction and ArchUnitNET.Fluent.LogicalConjunctionDefinition+ForwardSecondValueConjunction
    	ArchUnitNET.Fluent.Syntax.ConjunctionFactory does depend on System.Object
    	ArchUnitNET.Fluent.Syntax.SyntaxElement`1 does depend on System.Object and ArchUnitNET.Fluent.IHasDescription and ArchUnitNET.Fluent.IArchRuleCreator`1<TRuleType> and System.String and System.Boolean and ArchUnitNET.Fluent.Syntax.SyntaxElement`1<TRuleType> and System.Int32
    	ArchUnitNET.Fluent.Syntax.Elements.GivenObjectsConjunction`4 does depend on ArchUnitNET.Fluent.Syntax.Elements.GivenObjectsConjunctionWithDescription`3<TGivenRuleTypeThat,TRuleTypeShould,TRuleType> and ArchUnitNET.Fluent.IObjectProvider`1<TRuleType> and ArchUnitNET.Fluent.IHasDescription and ArchUnitNET.Fluent.IArchRuleCreator`1<TRuleType> and TGivenRuleTypeConjunctionWithReason and System.String and ArchUnitNET.Fluent.Syntax.ConjunctionFactory
    	ArchUnitNET.Fluent.Syntax.Elements.IComplexObjectConditions`2 does depend on ArchUnitNET.Fluent.Syntax.Elements.IObjectConditions`1<TRuleTypeShouldConjunction> and ArchUnitNET.Fluent.Syntax.Elements.Members.MethodMembers.ShouldRelateToMethodMembersThat`2<TRuleTypeShouldConjunction,TRuleType> and ArchUnitNET.Fluent.Syntax.Elements.Types.ShouldRelateToTypesThat`3<TRuleTypeShouldConjunction,ArchUnitNET.Domain.IType,TRuleType> and ArchUnitNET.Fluent.Syntax.Elements.Types.Attributes.ShouldRelateToAttributesThat`2<TRuleTypeShouldConjunction,TRuleType>
    	ArchUnitNET.Fluent.Syntax.Elements.ObjectsShouldConjunction`3 does depend on ArchUnitNET.Fluent.Syntax.Elements.ObjectsShouldConjunctionWithDescription`2<TRuleTypeShould,TRuleType> and ArchUnitNET.Fluent.IArchRule and ArchUnitNET.Fluent.ICanBeEvaluated and ArchUnitNET.Fluent.IHasDescription and ArchUnitNET.Fluent.IArchRuleCreator`1<TRuleType> and TRuleTypeShouldConjunctionWithReason and System.String and ArchUnitNET.Fluent.Syntax.ConjunctionFactory
    	ArchUnitNET.Fluent.Syntax.Elements.ObjectsShouldConjunctionWithDescription`2 does depend on ArchUnitNET.Fluent.ArchRule`1<TRuleType> and ArchUnitNET.Fluent.IArchRule and ArchUnitNET.Fluent.ICanBeEvaluated and ArchUnitNET.Fluent.IHasDescription and ArchUnitNET.Fluent.IArchRuleCreator`1<TRuleType> and TRuleTypeShould and ArchUnitNET.Fluent.Syntax.ConjunctionFactory
    	ArchUnitNET.Fluent.Syntax.Elements.Types.GivenTypes does depend on ArchUnitNET.Fluent.Syntax.Elements.GivenObjects`3<ArchUnitNET.Fluent.Syntax.Elements.Types.GivenTypesThat`2<ArchUnitNET.Fluent.Syntax.Elements.Types.GivenTypesConjunction,ArchUnitNET.Domain.IType>,ArchUnitNET.Fluent.Syntax.Elements.Types.TypesShould`2<ArchUnitNET.Fluent.Syntax.Elements.Types.TypesShouldConjunction,ArchUnitNET.Domain.IType>,ArchUnitNET.Domain.IType> and ArchUnitNET.Fluent.IObjectProvider`1<TRuleType> and ArchUnitNET.Fluent.IHasDescription and ArchUnitNET.Fluent.IArchRuleCreator`1<ArchUnitNET.Domain.IType>
    	ArchUnitNET.Fluent.Syntax.Elements.Types.GivenTypesConjunction does depend on ArchUnitNET.Fluent.Syntax.Elements.GivenObjectsConjunction`4<ArchUnitNET.Fluent.Syntax.Elements.Types.GivenTypesThat`2<ArchUnitNET.Fluent.Syntax.Elements.Types.GivenTypesConjunction,ArchUnitNET.Domain.IType>,ArchUnitNET.Fluent.Syntax.Elements.Types.TypesShould`2<ArchUnitNET.Fluent.Syntax.Elements.Types.TypesShouldConjunction,ArchUnitNET.Domain.IType>,ArchUnitNET.Fluent.Syntax.Elements.Types.GivenTypesConjunctionWithDescription,ArchUnitNET.Domain.IType> and ArchUnitNET.Fluent.IObjectProvider`1<TRuleType> and ArchUnitNET.Fluent.IHasDescription and ArchUnitNET.Fluent.IArchRuleCreator`1<ArchUnitNET.Domain.IType>
    	ArchUnitNET.Fluent.Syntax.Elements.Types.GivenTypesConjunctionWithDescription does depend on ArchUnitNET.Fluent.Syntax.Elements.GivenObjectsConjunctionWithDescription`3<ArchUnitNET.Fluent.Syntax.Elements.Types.GivenTypesThat`2<ArchUnitNET.Fluent.Syntax.Elements.Types.GivenTypesConjunction,ArchUnitNET.Domain.IType>,ArchUnitNET.Fluent.Syntax.Elements.Types.TypesShould`2<ArchUnitNET.Fluent.Syntax.Elements.Types.TypesShouldConjunction,ArchUnitNET.Domain.IType>,ArchUnitNET.Domain.IType> and ArchUnitNET.Fluent.IObjectProvider`1<TRuleType> and ArchUnitNET.Fluent.IHasDescription and ArchUnitNET.Fluent.IArchRuleCreator`1<ArchUnitNET.Domain.IType>
    	ArchUnitNET.Fluent.Syntax.Elements.Types.IComplexTypeConditions`2 does depend on ArchUnitNET.Fluent.Syntax.Elements.IComplexObjectConditions`2<TRuleTypeShouldConjunction,TRuleType> and ArchUnitNET.Fluent.Syntax.Elements.IObjectConditions`1<TRuleTypeShouldConjunction> and ArchUnitNET.Fluent.Syntax.Elements.Types.ITypeConditions`1<TRuleTypeShouldConjunction> and ArchUnitNET.Fluent.Syntax.Elements.Types.ShouldRelateToTypesThat`3<TRuleTypeShouldConjunction,ArchUnitNET.Domain.IType,TRuleType>
    	ArchUnitNET.Fluent.Syntax.Elements.Types.TypesShouldConjunction does depend on ArchUnitNET.Fluent.Syntax.Elements.ObjectsShouldConjunction`3<ArchUnitNET.Fluent.Syntax.Elements.Types.TypesShould`2<ArchUnitNET.Fluent.Syntax.Elements.Types.TypesShouldConjunction,ArchUnitNET.Domain.IType>,ArchUnitNET.Fluent.Syntax.Elements.Types.TypesShouldConjunctionWithDescription,ArchUnitNET.Domain.IType> and ArchUnitNET.Fluent.IArchRule and ArchUnitNET.Fluent.ICanBeEvaluated and ArchUnitNET.Fluent.IHasDescription and ArchUnitNET.Fluent.IArchRuleCreator`1<ArchUnitNET.Domain.IType>
    	ArchUnitNET.Fluent.Syntax.Elements.Types.TypesShouldConjunctionWithDescription does depend on ArchUnitNET.Fluent.Syntax.Elements.ObjectsShouldConjunctionWithDescription`2<ArchUnitNET.Fluent.Syntax.Elements.Types.TypesShould`2<ArchUnitNET.Fluent.Syntax.Elements.Types.TypesShouldConjunction,ArchUnitNET.Domain.IType>,ArchUnitNET.Domain.IType> and ArchUnitNET.Fluent.IArchRule and ArchUnitNET.Fluent.ICanBeEvaluated and ArchUnitNET.Fluent.IHasDescription and ArchUnitNET.Fluent.IArchRuleCreator`1<ArchUnitNET.Domain.IType>
    	ArchUnitNET.Fluent.Syntax.Elements.Types.Interfaces.GivenInterfaces does depend on ArchUnitNET.Fluent.Syntax.Elements.GivenObjects`3<ArchUnitNET.Fluent.Syntax.Elements.Types.Interfaces.GivenInterfacesThat,ArchUnitNET.Fluent.Syntax.Elements.Types.Interfaces.InterfacesShould,ArchUnitNET.Domain.Interface> and ArchUnitNET.Fluent.IObjectProvider`1<TRuleType> and ArchUnitNET.Fluent.IHasDescription and ArchUnitNET.Fluent.IArchRuleCreator`1<ArchUnitNET.Domain.Interface>
    	ArchUnitNET.Fluent.Syntax.Elements.Types.Interfaces.GivenInterfacesConjunction does depend on ArchUnitNET.Fluent.Syntax.Elements.GivenObjectsConjunction`4<ArchUnitNET.Fluent.Syntax.Elements.Types.Interfaces.GivenInterfacesThat,ArchUnitNET.Fluent.Syntax.Elements.Types.Interfaces.InterfacesShould,ArchUnitNET.Fluent.Syntax.Elements.Types.Interfaces.GivenInterfacesConjunction,ArchUnitNET.Domain.Interface> and ArchUnitNET.Fluent.IObjectProvider`1<TRuleType> and ArchUnitNET.Fluent.IHasDescription and ArchUnitNET.Fluent.IArchRuleCreator`1<ArchUnitNET.Domain.Interface>
    	ArchUnitNET.Fluent.Syntax.Elements.Types.Interfaces.GivenInterfacesConjunctionWithDescription does depend on ArchUnitNET.Fluent.Syntax.Elements.GivenObjectsConjunctionWithDescription`3<ArchUnitNET.Fluent.Syntax.Elements.Types.Interfaces.GivenInterfacesThat,ArchUnitNET.Fluent.Syntax.Elements.Types.Interfaces.InterfacesShould,ArchUnitNET.Domain.Interface> and ArchUnitNET.Fluent.IObjectProvider`1<TRuleType> and ArchUnitNET.Fluent.IHasDescription and ArchUnitNET.Fluent.IArchRuleCreator`1<ArchUnitNET.Domain.Interface>
    	ArchUnitNET.Fluent.Syntax.Elements.Types.Interfaces.GivenInterfacesThat does depend on ArchUnitNET.Fluent.Syntax.Elements.Types.GivenTypesThat`2<ArchUnitNET.Fluent.Syntax.Elements.Types.Interfaces.GivenInterfacesConjunction,ArchUnitNET.Domain.Interface> and ArchUnitNET.Fluent.Syntax.Elements.Types.Interfaces.IInterfacePredicates`1<ArchUnitNET.Fluent.Syntax.Elements.Types.Interfaces.GivenInterfacesConjunction> and ArchUnitNET.Fluent.Syntax.Elements.Types.ITypePredicates`1<ArchUnitNET.Fluent.Syntax.Elements.Types.Interfaces.GivenInterfacesConjunction> and ArchUnitNET.Fluent.Syntax.Elements.IObjectPredicates`1<ArchUnitNET.Fluent.Syntax.Elements.Types.Interfaces.GivenInterfacesConjunction> and ArchUnitNET.Fluent.Syntax.Elements.Types.ITypePredicates`1<TGivenRuleTypeConjunction> and ArchUnitNET.Fluent.Syntax.Elements.IObjectPredicates`1<TGivenRuleTypeConjunction> and ArchUnitNET.Fluent.IHasDescription and ArchUnitNET.Fluent.IArchRuleCreator`1<ArchUnitNET.Domain.Interface>
    	ArchUnitNET.Fluent.Syntax.Elements.Types.Interfaces.IComplexInterfaceConditions does depend on ArchUnitNET.Fluent.Syntax.Elements.Types.IComplexTypeConditions`2<ArchUnitNET.Fluent.Syntax.Elements.Types.Interfaces.InterfacesShouldConjunction,ArchUnitNET.Domain.Interface> and ArchUnitNET.Fluent.Syntax.Elements.IComplexObjectConditions`2<ArchUnitNET.Fluent.Syntax.Elements.Types.Interfaces.InterfacesShouldConjunction,ArchUnitNET.Domain.Interface> and ArchUnitNET.Fluent.Syntax.Elements.IObjectConditions`1<ArchUnitNET.Fluent.Syntax.Elements.Types.Interfaces.InterfacesShouldConjunction> and ArchUnitNET.Fluent.Syntax.Elements.Types.ITypeConditions`1<ArchUnitNET.Fluent.Syntax.Elements.Types.Interfaces.InterfacesShouldConjunction> and ArchUnitNET.Fluent.Syntax.Elements.Types.Interfaces.IInterfaceConditions`1<ArchUnitNET.Fluent.Syntax.Elements.Types.Interfaces.InterfacesShouldConjunction>
    	ArchUnitNET.Fluent.Syntax.Elements.Types.Interfaces.IInterfaceConditions`1 does depend on ArchUnitNET.Fluent.Syntax.Elements.Types.ITypeConditions`1<TReturnType> and ArchUnitNET.Fluent.Syntax.Elements.IObjectConditions`1<TReturnType>
    	ArchUnitNET.Fluent.Syntax.Elements.Types.Interfaces.IInterfacePredicates`1 does depend on ArchUnitNET.Fluent.Syntax.Elements.Types.ITypePredicates`1<TReturnType> and ArchUnitNET.Fluent.Syntax.Elements.IObjectPredicates`1<TReturnType>
    	ArchUnitNET.Fluent.Syntax.Elements.Types.Interfaces.InterfacesShould does depend on ArchUnitNET.Fluent.Syntax.Elements.Types.TypesShould`2<ArchUnitNET.Fluent.Syntax.Elements.Types.Interfaces.InterfacesShouldConjunction,ArchUnitNET.Domain.Interface> and ArchUnitNET.Fluent.Syntax.Elements.Types.Interfaces.IComplexInterfaceConditions and ArchUnitNET.Fluent.Syntax.Elements.Types.IComplexTypeConditions`2<ArchUnitNET.Fluent.Syntax.Elements.Types.Interfaces.InterfacesShouldConjunction,ArchUnitNET.Domain.Interface> and ArchUnitNET.Fluent.Syntax.Elements.IComplexObjectConditions`2<ArchUnitNET.Fluent.Syntax.Elements.Types.Interfaces.InterfacesShouldConjunction,ArchUnitNET.Domain.Interface> and ArchUnitNET.Fluent.Syntax.Elements.IObjectConditions`1<ArchUnitNET.Fluent.Syntax.Elements.Types.Interfaces.InterfacesShouldConjunction> and ArchUnitNET.Fluent.Syntax.Elements.Types.ITypeConditions`1<ArchUnitNET.Fluent.Syntax.Elements.Types.Interfaces.InterfacesShouldConjunction> and ArchUnitNET.Fluent.Syntax.Elements.Types.Interfaces.IInterfaceConditions`1<ArchUnitNET.Fluent.Syntax.Elements.Types.Interfaces.InterfacesShouldConjunction> and ArchUnitNET.Fluent.Syntax.Elements.Types.IComplexTypeConditions`2<TRuleTypeShouldConjunction,TRuleType> and ArchUnitNET.Fluent.Syntax.Elements.IComplexObjectConditions`2<TRuleTypeShouldConjunction,TRuleType> and ArchUnitNET.Fluent.Syntax.Elements.IObjectConditions`1<TRuleTypeShouldConjunction> and ArchUnitNET.Fluent.Syntax.Elements.Types.ITypeConditions`1<TRuleTypeShouldConjunction> and ArchUnitNET.Fluent.IHasDescription and ArchUnitNET.Fluent.IArchRuleCreator`1<ArchUnitNET.Domain.Interface>
    	ArchUnitNET.Fluent.Syntax.Elements.Types.Interfaces.InterfacesShouldConjunction does depend on ArchUnitNET.Fluent.Syntax.Elements.ObjectsShouldConjunction`3<ArchUnitNET.Fluent.Syntax.Elements.Types.Interfaces.InterfacesShould,ArchUnitNET.Fluent.Syntax.Elements.Types.Interfaces.InterfacesShouldConjunctionWithDescription,ArchUnitNET.Domain.Interface> and ArchUnitNET.Fluent.IArchRule and ArchUnitNET.Fluent.ICanBeEvaluated and ArchUnitNET.Fluent.IHasDescription and ArchUnitNET.Fluent.IArchRuleCreator`1<ArchUnitNET.Domain.Interface>
    	ArchUnitNET.Fluent.Syntax.Elements.Types.Interfaces.InterfacesShouldConjunctionWithDescription does depend on ArchUnitNET.Fluent.Syntax.Elements.ObjectsShouldConjunctionWithDescription`2<ArchUnitNET.Fluent.Syntax.Elements.Types.Interfaces.InterfacesShould,ArchUnitNET.Domain.Interface> and ArchUnitNET.Fluent.IArchRule and ArchUnitNET.Fluent.ICanBeEvaluated and ArchUnitNET.Fluent.IHasDescription and ArchUnitNET.Fluent.IArchRuleCreator`1<ArchUnitNET.Domain.Interface>
    	ArchUnitNET.Fluent.Syntax.Elements.Types.Interfaces.ShouldRelateToInterfacesThat`2 does depend on ArchUnitNET.Fluent.Syntax.Elements.Types.ShouldRelateToTypesThat`3<TRuleTypeShouldConjunction,ArchUnitNET.Domain.Interface,TRuleType> and ArchUnitNET.Fluent.Syntax.Elements.Types.Interfaces.IInterfacePredicates`1<TRuleTypeShouldConjunction> and ArchUnitNET.Fluent.Syntax.Elements.Types.ITypePredicates`1<TRuleTypeShouldConjunction> and ArchUnitNET.Fluent.Syntax.Elements.IObjectPredicates`1<TRuleTypeShouldConjunction> and ArchUnitNET.Fluent.IHasDescription and ArchUnitNET.Fluent.IArchRuleCreator`1<TRuleType>
    	ArchUnitNET.Fluent.Syntax.Elements.Types.Classes.ClassConditionsDefinition does depend on System.Object and ArchUnitNET.Fluent.Conditions.ICondition`1<ArchUnitNET.Domain.Class> and ArchUnitNET.Fluent.Syntax.Elements.Types.Classes.ClassConditionsDefinition+<>c
    	ArchUnitNET.Fluent.Syntax.Elements.Types.Classes.ClassesShould does depend on ArchUnitNET.Fluent.Syntax.Elements.Types.TypesShould`2<ArchUnitNET.Fluent.Syntax.Elements.Types.Classes.ClassesShouldConjunction,ArchUnitNET.Domain.Class> and ArchUnitNET.Fluent.Syntax.Elements.Types.Classes.IComplexClassConditions and ArchUnitNET.Fluent.Syntax.Elements.Types.IComplexTypeConditions`2<ArchUnitNET.Fluent.Syntax.Elements.Types.Classes.ClassesShouldConjunction,ArchUnitNET.Domain.Class> and ArchUnitNET.Fluent.Syntax.Elements.IComplexObjectConditions`2<ArchUnitNET.Fluent.Syntax.Elements.Types.Classes.ClassesShouldConjunction,ArchUnitNET.Domain.Class> and ArchUnitNET.Fluent.Syntax.Elements.IObjectConditions`1<ArchUnitNET.Fluent.Syntax.Elements.Types.Classes.ClassesShouldConjunction> and ArchUnitNET.Fluent.Syntax.Elements.Types.ITypeConditions`1<ArchUnitNET.Fluent.Syntax.Elements.Types.Classes.ClassesShouldConjunction> and ArchUnitNET.Fluent.Syntax.Elements.Types.Classes.IClassConditions`1<ArchUnitNET.Fluent.Syntax.Elements.Types.Classes.ClassesShouldConjunction> and ArchUnitNET.Fluent.Syntax.Elements.Types.IComplexTypeConditions`2<TRuleTypeShouldConjunction,TRuleType> and ArchUnitNET.Fluent.Syntax.Elements.IComplexObjectConditions`2<TRuleTypeShouldConjunction,TRuleType> and ArchUnitNET.Fluent.Syntax.Elements.IObjectConditions`1<TRuleTypeShouldConjunction> and ArchUnitNET.Fluent.Syntax.Elements.Types.ITypeConditions`1<TRuleTypeShouldConjunction> and ArchUnitNET.Fluent.IHasDescription and ArchUnitNET.Fluent.IArchRuleCreator`1<ArchUnitNET.Domain.Class> and ArchUnitNET.Fluent.Syntax.Elements.Types.Classes.ClassesShouldConjunction and ArchUnitNET.Fluent.Syntax.Elements.Types.Classes.ClassConditionsDefinition
    	ArchUnitNET.Fluent.Syntax.Elements.Types.Classes.ClassesShouldConjunction does depend on ArchUnitNET.Fluent.Syntax.Elements.ObjectsShouldConjunction`3<ArchUnitNET.Fluent.Syntax.Elements.Types.Classes.ClassesShould,ArchUnitNET.Fluent.Syntax.Elements.Types.Classes.ClassesShouldConjunctionWithDescription,ArchUnitNET.Domain.Class> and ArchUnitNET.Fluent.IArchRule and ArchUnitNET.Fluent.ICanBeEvaluated and ArchUnitNET.Fluent.IHasDescription and ArchUnitNET.Fluent.IArchRuleCreator`1<ArchUnitNET.Domain.Class>
    	ArchUnitNET.Fluent.Syntax.Elements.Types.Classes.ClassesShouldConjunctionWithDescription does depend on ArchUnitNET.Fluent.Syntax.Elements.ObjectsShouldConjunctionWithDescription`2<ArchUnitNET.Fluent.Syntax.Elements.Types.Classes.ClassesShould,ArchUnitNET.Domain.Class> and ArchUnitNET.Fluent.IArchRule and ArchUnitNET.Fluent.ICanBeEvaluated and ArchUnitNET.Fluent.IHasDescription and ArchUnitNET.Fluent.IArchRuleCreator`1<ArchUnitNET.Domain.Class>
    	ArchUnitNET.Fluent.Syntax.Elements.Types.Classes.ClassPredicatesDefinition does depend on System.Object and ArchUnitNET.Fluent.Predicates.IPredicate`1<ArchUnitNET.Domain.Class> and ArchUnitNET.Fluent.Syntax.Elements.Types.Classes.ClassPredicatesDefinition+<>c
    	ArchUnitNET.Fluent.Syntax.Elements.Types.Classes.GivenClasses does depend on ArchUnitNET.Fluent.Syntax.Elements.GivenObjects`3<ArchUnitNET.Fluent.Syntax.Elements.Types.Classes.GivenClassesThat,ArchUnitNET.Fluent.Syntax.Elements.Types.Classes.ClassesShould,ArchUnitNET.Domain.Class> and ArchUnitNET.Fluent.IObjectProvider`1<TRuleType> and ArchUnitNET.Fluent.IHasDescription and ArchUnitNET.Fluent.IArchRuleCreator`1<ArchUnitNET.Domain.Class>
    	ArchUnitNET.Fluent.Syntax.Elements.Types.Classes.GivenClassesConjunction does depend on ArchUnitNET.Fluent.Syntax.Elements.GivenObjectsConjunction`4<ArchUnitNET.Fluent.Syntax.Elements.Types.Classes.GivenClassesThat,ArchUnitNET.Fluent.Syntax.Elements.Types.Classes.ClassesShould,ArchUnitNET.Fluent.Syntax.Elements.Types.Classes.GivenClassesConjunctionWithDescription,ArchUnitNET.Domain.Class> and ArchUnitNET.Fluent.IObjectProvider`1<TRuleType> and ArchUnitNET.Fluent.IHasDescription and ArchUnitNET.Fluent.IArchRuleCreator`1<ArchUnitNET.Domain.Class>
    	ArchUnitNET.Fluent.Syntax.Elements.Types.Classes.GivenClassesConjunctionWithDescription does depend on ArchUnitNET.Fluent.Syntax.Elements.GivenObjectsConjunctionWithDescription`3<ArchUnitNET.Fluent.Syntax.Elements.Types.Classes.GivenClassesThat,ArchUnitNET.Fluent.Syntax.Elements.Types.Classes.ClassesShould,ArchUnitNET.Domain.Class> and ArchUnitNET.Fluent.IObjectProvider`1<TRuleType> and ArchUnitNET.Fluent.IHasDescription and ArchUnitNET.Fluent.IArchRuleCreator`1<ArchUnitNET.Domain.Class>
    	ArchUnitNET.Fluent.Syntax.Elements.Types.Classes.GivenClassesThat does depend on ArchUnitNET.Fluent.Syntax.Elements.Types.GivenTypesThat`2<ArchUnitNET.Fluent.Syntax.Elements.Types.Classes.GivenClassesConjunction,ArchUnitNET.Domain.Class> and ArchUnitNET.Fluent.Syntax.Elements.Types.Classes.IClassPredicates`1<ArchUnitNET.Fluent.Syntax.Elements.Types.Classes.GivenClassesConjunction> and ArchUnitNET.Fluent.Syntax.Elements.Types.ITypePredicates`1<ArchUnitNET.Fluent.Syntax.Elements.Types.Classes.GivenClassesConjunction> and ArchUnitNET.Fluent.Syntax.Elements.IObjectPredicates`1<ArchUnitNET.Fluent.Syntax.Elements.Types.Classes.GivenClassesConjunction> and ArchUnitNET.Fluent.Syntax.Elements.Types.ITypePredicates`1<TGivenRuleTypeConjunction> and ArchUnitNET.Fluent.Syntax.Elements.IObjectPredicates`1<TGivenRuleTypeConjunction> and ArchUnitNET.Fluent.IHasDescription and ArchUnitNET.Fluent.IArchRuleCreator`1<ArchUnitNET.Domain.Class> and ArchUnitNET.Fluent.Syntax.Elements.Types.Classes.GivenClassesConjunction and ArchUnitNET.Fluent.Syntax.Elements.Types.Classes.ClassPredicatesDefinition
    	ArchUnitNET.Fluent.Syntax.Elements.Types.Classes.IClassConditions`1 does depend on ArchUnitNET.Fluent.Syntax.Elements.Types.ITypeConditions`1<TReturnType> and ArchUnitNET.Fluent.Syntax.Elements.IObjectConditions`1<TReturnType> and TReturnType
    	ArchUnitNET.Fluent.Syntax.Elements.Types.Classes.IClassPredicates`1 does depend on ArchUnitNET.Fluent.Syntax.Elements.Types.ITypePredicates`1<TReturnType> and ArchUnitNET.Fluent.Syntax.Elements.IObjectPredicates`1<TReturnType> and TReturnType
    	ArchUnitNET.Fluent.Syntax.Elements.Types.Classes.IComplexClassConditions does depend on ArchUnitNET.Fluent.Syntax.Elements.Types.IComplexTypeConditions`2<ArchUnitNET.Fluent.Syntax.Elements.Types.Classes.ClassesShouldConjunction,ArchUnitNET.Domain.Class> and ArchUnitNET.Fluent.Syntax.Elements.IComplexObjectConditions`2<ArchUnitNET.Fluent.Syntax.Elements.Types.Classes.ClassesShouldConjunction,ArchUnitNET.Domain.Class> and ArchUnitNET.Fluent.Syntax.Elements.IObjectConditions`1<ArchUnitNET.Fluent.Syntax.Elements.Types.Classes.ClassesShouldConjunction> and ArchUnitNET.Fluent.Syntax.Elements.Types.ITypeConditions`1<ArchUnitNET.Fluent.Syntax.Elements.Types.Classes.ClassesShouldConjunction> and ArchUnitNET.Fluent.Syntax.Elements.Types.Classes.IClassConditions`1<ArchUnitNET.Fluent.Syntax.Elements.Types.Classes.ClassesShouldConjunction>
    	ArchUnitNET.Fluent.Syntax.Elements.Types.Classes.ShouldRelateToClassesThat`2 does depend on ArchUnitNET.Fluent.Syntax.Elements.Types.ShouldRelateToTypesThat`3<TRuleTypeShouldConjunction,ArchUnitNET.Domain.Class,TRuleType> and ArchUnitNET.Fluent.Syntax.Elements.Types.Classes.IClassPredicates`1<TRuleTypeShouldConjunction> and ArchUnitNET.Fluent.Syntax.Elements.Types.ITypePredicates`1<TRuleTypeShouldConjunction> and ArchUnitNET.Fluent.Syntax.Elements.IObjectPredicates`1<TRuleTypeShouldConjunction> and ArchUnitNET.Fluent.IHasDescription and ArchUnitNET.Fluent.IArchRuleCreator`1<TRuleType> and TRuleTypeShouldConjunction and ArchUnitNET.Fluent.Syntax.Elements.Types.Classes.ClassPredicatesDefinition and ArchUnitNET.Fluent.Syntax.ConjunctionFactory
    	ArchUnitNET.Fluent.Syntax.Elements.Types.Attributes.AttributeConditionsDefinition does depend on System.Object and ArchUnitNET.Fluent.Conditions.ICondition`1<ArchUnitNET.Domain.Attribute> and ArchUnitNET.Fluent.Syntax.Elements.Types.Attributes.AttributeConditionsDefinition+<>c
    	ArchUnitNET.Fluent.Syntax.Elements.Types.Attributes.AttributePredicatesDefinition does depend on System.Object and ArchUnitNET.Fluent.Predicates.IPredicate`1<ArchUnitNET.Domain.Attribute> and ArchUnitNET.Fluent.Syntax.Elements.Types.Attributes.AttributePredicatesDefinition+<>c
    	ArchUnitNET.Fluent.Syntax.Elements.Types.Attributes.AttributesShould does depend on ArchUnitNET.Fluent.Syntax.Elements.Types.TypesShould`2<ArchUnitNET.Fluent.Syntax.Elements.Types.Attributes.AttributesShouldConjunction,ArchUnitNET.Domain.Attribute> and ArchUnitNET.Fluent.Syntax.Elements.Types.Attributes.IComplexAttributeConditions and ArchUnitNET.Fluent.Syntax.Elements.Types.IComplexTypeConditions`2<ArchUnitNET.Fluent.Syntax.Elements.Types.Attributes.AttributesShouldConjunction,ArchUnitNET.Domain.Attribute> and ArchUnitNET.Fluent.Syntax.Elements.IComplexObjectConditions`2<ArchUnitNET.Fluent.Syntax.Elements.Types.Attributes.AttributesShouldConjunction,ArchUnitNET.Domain.Attribute> and ArchUnitNET.Fluent.Syntax.Elements.IObjectConditions`1<ArchUnitNET.Fluent.Syntax.Elements.Types.Attributes.AttributesShouldConjunction> and ArchUnitNET.Fluent.Syntax.Elements.Types.ITypeConditions`1<ArchUnitNET.Fluent.Syntax.Elements.Types.Attributes.AttributesShouldConjunction> and ArchUnitNET.Fluent.Syntax.Elements.Types.Attributes.IAttributeConditions`1<ArchUnitNET.Fluent.Syntax.Elements.Types.Attributes.AttributesShouldConjunction> and ArchUnitNET.Fluent.Syntax.Elements.Types.IComplexTypeConditions`2<TRuleTypeShouldConjunction,TRuleType> and ArchUnitNET.Fluent.Syntax.Elements.IComplexObjectConditions`2<TRuleTypeShouldConjunction,TRuleType> and ArchUnitNET.Fluent.Syntax.Elements.IObjectConditions`1<TRuleTypeShouldConjunction> and ArchUnitNET.Fluent.Syntax.Elements.Types.ITypeConditions`1<TRuleTypeShouldConjunction> and ArchUnitNET.Fluent.IHasDescription and ArchUnitNET.Fluent.IArchRuleCreator`1<ArchUnitNET.Domain.Attribute> and ArchUnitNET.Fluent.Syntax.Elements.Types.Attributes.AttributesShouldConjunction and ArchUnitNET.Fluent.Syntax.Elements.Types.Attributes.AttributeConditionsDefinition
    	ArchUnitNET.Fluent.Syntax.Elements.Types.Attributes.AttributesShouldConjunction does depend on ArchUnitNET.Fluent.Syntax.Elements.ObjectsShouldConjunction`3<ArchUnitNET.Fluent.Syntax.Elements.Types.Attributes.AttributesShould,ArchUnitNET.Fluent.Syntax.Elements.Types.Attributes.AttributesShouldConjunctionWithDescription,ArchUnitNET.Domain.Attribute> and ArchUnitNET.Fluent.IArchRule and ArchUnitNET.Fluent.ICanBeEvaluated and ArchUnitNET.Fluent.IHasDescription and ArchUnitNET.Fluent.IArchRuleCreator`1<ArchUnitNET.Domain.Attribute>
    	ArchUnitNET.Fluent.Syntax.Elements.Types.Attributes.AttributesShouldConjunctionWithDescription does depend on ArchUnitNET.Fluent.Syntax.Elements.ObjectsShouldConjunctionWithDescription`2<ArchUnitNET.Fluent.Syntax.Elements.Types.Attributes.AttributesShould,ArchUnitNET.Domain.Attribute> and ArchUnitNET.Fluent.IArchRule and ArchUnitNET.Fluent.ICanBeEvaluated and ArchUnitNET.Fluent.IHasDescription and ArchUnitNET.Fluent.IArchRuleCreator`1<ArchUnitNET.Domain.Attribute>
    	ArchUnitNET.Fluent.Syntax.Elements.Types.Attributes.GivenAttributes does depend on ArchUnitNET.Fluent.Syntax.Elements.GivenObjects`3<ArchUnitNET.Fluent.Syntax.Elements.Types.Attributes.GivenAttributesThat,ArchUnitNET.Fluent.Syntax.Elements.Types.Attributes.AttributesShould,ArchUnitNET.Domain.Attribute> and ArchUnitNET.Fluent.IObjectProvider`1<TRuleType> and ArchUnitNET.Fluent.IHasDescription and ArchUnitNET.Fluent.IArchRuleCreator`1<ArchUnitNET.Domain.Attribute>
    	ArchUnitNET.Fluent.Syntax.Elements.Types.Attributes.GivenAttributesConjunction does depend on ArchUnitNET.Fluent.Syntax.Elements.GivenObjectsConjunction`4<ArchUnitNET.Fluent.Syntax.Elements.Types.Attributes.GivenAttributesThat,ArchUnitNET.Fluent.Syntax.Elements.Types.Attributes.AttributesShould,ArchUnitNET.Fluent.Syntax.Elements.Types.Attributes.GivenAttributesConjunctionWithDescription,ArchUnitNET.Domain.Attribute> and ArchUnitNET.Fluent.IObjectProvider`1<TRuleType> and ArchUnitNET.Fluent.IHasDescription and ArchUnitNET.Fluent.IArchRuleCreator`1<ArchUnitNET.Domain.Attribute>
    	ArchUnitNET.Fluent.Syntax.Elements.Types.Attributes.GivenAttributesConjunctionWithDescription does depend on ArchUnitNET.Fluent.Syntax.Elements.GivenObjectsConjunctionWithDescription`3<ArchUnitNET.Fluent.Syntax.Elements.Types.Attributes.GivenAttributesThat,ArchUnitNET.Fluent.Syntax.Elements.Types.Attributes.AttributesShould,ArchUnitNET.Domain.Attribute> and ArchUnitNET.Fluent.IObjectProvider`1<TRuleType> and ArchUnitNET.Fluent.IHasDescription and ArchUnitNET.Fluent.IArchRuleCreator`1<ArchUnitNET.Domain.Attribute>
    	ArchUnitNET.Fluent.Syntax.Elements.Types.Attributes.GivenAttributesThat does depend on ArchUnitNET.Fluent.Syntax.Elements.Types.GivenTypesThat`2<ArchUnitNET.Fluent.Syntax.Elements.Types.Attributes.GivenAttributesConjunction,ArchUnitNET.Domain.Attribute> and ArchUnitNET.Fluent.Syntax.Elements.Types.Attributes.IAttributePredicates`1<ArchUnitNET.Fluent.Syntax.Elements.Types.Attributes.GivenAttributesConjunction> and ArchUnitNET.Fluent.Syntax.Elements.Types.ITypePredicates`1<ArchUnitNET.Fluent.Syntax.Elements.Types.Attributes.GivenAttributesConjunction> and ArchUnitNET.Fluent.Syntax.Elements.IObjectPredicates`1<ArchUnitNET.Fluent.Syntax.Elements.Types.Attributes.GivenAttributesConjunction> and ArchUnitNET.Fluent.Syntax.Elements.Types.ITypePredicates`1<TGivenRuleTypeConjunction> and ArchUnitNET.Fluent.Syntax.Elements.IObjectPredicates`1<TGivenRuleTypeConjunction> and ArchUnitNET.Fluent.IHasDescription and ArchUnitNET.Fluent.IArchRuleCreator`1<ArchUnitNET.Domain.Attribute> and ArchUnitNET.Fluent.Syntax.Elements.Types.Attributes.GivenAttributesConjunction and ArchUnitNET.Fluent.Syntax.Elements.Types.Attributes.AttributePredicatesDefinition
    	ArchUnitNET.Fluent.Syntax.Elements.Types.Attributes.IAttributeConditions`1 does depend on ArchUnitNET.Fluent.Syntax.Elements.Types.ITypeConditions`1<TReturnType> and ArchUnitNET.Fluent.Syntax.Elements.IObjectConditions`1<TReturnType> and TReturnType
    	ArchUnitNET.Fluent.Syntax.Elements.Types.Attributes.IAttributePredicates`1 does depend on ArchUnitNET.Fluent.Syntax.Elements.Types.ITypePredicates`1<TReturnType> and ArchUnitNET.Fluent.Syntax.Elements.IObjectPredicates`1<TReturnType> and TReturnType
    	ArchUnitNET.Fluent.Syntax.Elements.Types.Attributes.IComplexAttributeConditions does depend on ArchUnitNET.Fluent.Syntax.Elements.Types.IComplexTypeConditions`2<ArchUnitNET.Fluent.Syntax.Elements.Types.Attributes.AttributesShouldConjunction,ArchUnitNET.Domain.Attribute> and ArchUnitNET.Fluent.Syntax.Elements.IComplexObjectConditions`2<ArchUnitNET.Fluent.Syntax.Elements.Types.Attributes.AttributesShouldConjunction,ArchUnitNET.Domain.Attribute> and ArchUnitNET.Fluent.Syntax.Elements.IObjectConditions`1<ArchUnitNET.Fluent.Syntax.Elements.Types.Attributes.AttributesShouldConjunction> and ArchUnitNET.Fluent.Syntax.Elements.Types.ITypeConditions`1<ArchUnitNET.Fluent.Syntax.Elements.Types.Attributes.AttributesShouldConjunction> and ArchUnitNET.Fluent.Syntax.Elements.Types.Attributes.IAttributeConditions`1<ArchUnitNET.Fluent.Syntax.Elements.Types.Attributes.AttributesShouldConjunction>
    	ArchUnitNET.Fluent.Syntax.Elements.Types.Attributes.ShouldRelateToAttributesThat`2 does depend on ArchUnitNET.Fluent.Syntax.Elements.Types.ShouldRelateToTypesThat`3<TRuleTypeShouldConjunction,ArchUnitNET.Domain.Attribute,TRuleType> and ArchUnitNET.Fluent.Syntax.Elements.Types.Attributes.IAttributePredicates`1<TRuleTypeShouldConjunction> and ArchUnitNET.Fluent.Syntax.Elements.Types.ITypePredicates`1<TRuleTypeShouldConjunction> and ArchUnitNET.Fluent.Syntax.Elements.IObjectPredicates`1<TRuleTypeShouldConjunction> and ArchUnitNET.Fluent.IHasDescription and ArchUnitNET.Fluent.IArchRuleCreator`1<TRuleType> and TRuleTypeShouldConjunction and ArchUnitNET.Fluent.Syntax.Elements.Types.Attributes.AttributePredicatesDefinition and ArchUnitNET.Fluent.Syntax.ConjunctionFactory
    	ArchUnitNET.Fluent.Syntax.Elements.Members.GivenMembers does depend on ArchUnitNET.Fluent.Syntax.Elements.GivenObjects`3<ArchUnitNET.Fluent.Syntax.Elements.Members.GivenMembersThat`2<ArchUnitNET.Fluent.Syntax.Elements.Members.GivenMembersConjunction,ArchUnitNET.Domain.IMember>,ArchUnitNET.Fluent.Syntax.Elements.Members.MembersShould`2<ArchUnitNET.Fluent.Syntax.Elements.Members.MembersShouldConjunction,ArchUnitNET.Domain.IMember>,ArchUnitNET.Domain.IMember> and ArchUnitNET.Fluent.IObjectProvider`1<TRuleType> and ArchUnitNET.Fluent.IHasDescription and ArchUnitNET.Fluent.IArchRuleCreator`1<ArchUnitNET.Domain.IMember>
    	ArchUnitNET.Fluent.Syntax.Elements.Members.GivenMembersConjunction does depend on ArchUnitNET.Fluent.Syntax.Elements.GivenObjectsConjunction`4<ArchUnitNET.Fluent.Syntax.Elements.Members.GivenMembersThat`2<ArchUnitNET.Fluent.Syntax.Elements.Members.GivenMembersConjunction,ArchUnitNET.Domain.IMember>,ArchUnitNET.Fluent.Syntax.Elements.Members.MembersShould`2<ArchUnitNET.Fluent.Syntax.Elements.Members.MembersShouldConjunction,ArchUnitNET.Domain.IMember>,ArchUnitNET.Fluent.Syntax.Elements.Members.GivenMembersConjunctionWithDescription,ArchUnitNET.Domain.IMember> and ArchUnitNET.Fluent.IObjectProvider`1<TRuleType> and ArchUnitNET.Fluent.IHasDescription and ArchUnitNET.Fluent.IArchRuleCreator`1<ArchUnitNET.Domain.IMember>
    	ArchUnitNET.Fluent.Syntax.Elements.Members.GivenMembersConjunctionWithDescription does depend on ArchUnitNET.Fluent.Syntax.Elements.GivenObjectsConjunctionWithDescription`3<ArchUnitNET.Fluent.Syntax.Elements.Members.GivenMembersThat`2<ArchUnitNET.Fluent.Syntax.Elements.Members.GivenMembersConjunction,ArchUnitNET.Domain.IMember>,ArchUnitNET.Fluent.Syntax.Elements.Members.MembersShould`2<ArchUnitNET.Fluent.Syntax.Elements.Members.MembersShouldConjunction,ArchUnitNET.Domain.IMember>,ArchUnitNET.Domain.IMember> and ArchUnitNET.Fluent.IObjectProvider`1<TRuleType> and ArchUnitNET.Fluent.IHasDescription and ArchUnitNET.Fluent.IArchRuleCreator`1<ArchUnitNET.Domain.IMember>
    	ArchUnitNET.Fluent.Syntax.Elements.Members.IComplexMemberConditions`2 does depend on ArchUnitNET.Fluent.Syntax.Elements.IComplexObjectConditions`2<TRuleTypeShouldConjunction,TRuleType> and ArchUnitNET.Fluent.Syntax.Elements.IObjectConditions`1<TRuleTypeShouldConjunction> and ArchUnitNET.Fluent.Syntax.Elements.Members.IMemberConditions`1<TRuleTypeShouldConjunction> and ArchUnitNET.Fluent.Syntax.Elements.Types.ShouldRelateToTypesThat`3<TRuleTypeShouldConjunction,ArchUnitNET.Domain.IType,TRuleType>
    	ArchUnitNET.Fluent.Syntax.Elements.Members.MembersShouldConjunction does depend on ArchUnitNET.Fluent.Syntax.Elements.ObjectsShouldConjunction`3<ArchUnitNET.Fluent.Syntax.Elements.Members.MembersShould`2<ArchUnitNET.Fluent.Syntax.Elements.Members.MembersShouldConjunction,ArchUnitNET.Domain.IMember>,ArchUnitNET.Fluent.Syntax.Elements.Members.MembersShouldConjunctionWithDescription,ArchUnitNET.Domain.IMember> and ArchUnitNET.Fluent.IArchRule and ArchUnitNET.Fluent.ICanBeEvaluated and ArchUnitNET.Fluent.IHasDescription and ArchUnitNET.Fluent.IArchRuleCreator`1<ArchUnitNET.Domain.IMember>
    	ArchUnitNET.Fluent.Syntax.Elements.Members.MembersShouldConjunctionWithDescription does depend on ArchUnitNET.Fluent.Syntax.Elements.ObjectsShouldConjunctionWithDescription`2<ArchUnitNET.Fluent.Syntax.Elements.Members.MembersShould`2<ArchUnitNET.Fluent.Syntax.Elements.Members.MembersShouldConjunction,ArchUnitNET.Domain.IMember>,ArchUnitNET.Domain.IMember> and ArchUnitNET.Fluent.IArchRule and ArchUnitNET.Fluent.ICanBeEvaluated and ArchUnitNET.Fluent.IHasDescription and ArchUnitNET.Fluent.IArchRuleCreator`1<ArchUnitNET.Domain.IMember>
    	ArchUnitNET.Fluent.Syntax.Elements.Members.PropertyMembers.GivenPropertyMembers does depend on ArchUnitNET.Fluent.Syntax.Elements.GivenObjects`3<ArchUnitNET.Fluent.Syntax.Elements.Members.PropertyMembers.GivenPropertyMembersThat,ArchUnitNET.Fluent.Syntax.Elements.Members.PropertyMembers.PropertyMembersShould,ArchUnitNET.Domain.PropertyMember> and ArchUnitNET.Fluent.IObjectProvider`1<TRuleType> and ArchUnitNET.Fluent.IHasDescription and ArchUnitNET.Fluent.IArchRuleCreator`1<ArchUnitNET.Domain.PropertyMember>
    	ArchUnitNET.Fluent.Syntax.Elements.Members.PropertyMembers.GivenPropertyMembersConjunction does depend on ArchUnitNET.Fluent.Syntax.Elements.GivenObjectsConjunction`4<ArchUnitNET.Fluent.Syntax.Elements.Members.PropertyMembers.GivenPropertyMembersThat,ArchUnitNET.Fluent.Syntax.Elements.Members.PropertyMembers.PropertyMembersShould,ArchUnitNET.Fluent.Syntax.Elements.Members.PropertyMembers.GivenPropertyMembersConjunctionWithDescription,ArchUnitNET.Domain.PropertyMember> and ArchUnitNET.Fluent.IObjectProvider`1<TRuleType> and ArchUnitNET.Fluent.IHasDescription and ArchUnitNET.Fluent.IArchRuleCreator`1<ArchUnitNET.Domain.PropertyMember>
    	ArchUnitNET.Fluent.Syntax.Elements.Members.PropertyMembers.GivenPropertyMembersConjunctionWithDescription does depend on ArchUnitNET.Fluent.Syntax.Elements.GivenObjectsConjunctionWithDescription`3<ArchUnitNET.Fluent.Syntax.Elements.Members.PropertyMembers.GivenPropertyMembersThat,ArchUnitNET.Fluent.Syntax.Elements.Members.PropertyMembers.PropertyMembersShould,ArchUnitNET.Domain.PropertyMember> and ArchUnitNET.Fluent.IObjectProvider`1<TRuleType> and ArchUnitNET.Fluent.IHasDescription and ArchUnitNET.Fluent.IArchRuleCreator`1<ArchUnitNET.Domain.PropertyMember>
    	ArchUnitNET.Fluent.Syntax.Elements.Members.PropertyMembers.GivenPropertyMembersThat does depend on ArchUnitNET.Fluent.Syntax.Elements.Members.GivenMembersThat`2<ArchUnitNET.Fluent.Syntax.Elements.Members.PropertyMembers.GivenPropertyMembersConjunction,ArchUnitNET.Domain.PropertyMember> and ArchUnitNET.Fluent.Syntax.Elements.Members.PropertyMembers.IPropertyMemberPredicates`1<ArchUnitNET.Fluent.Syntax.Elements.Members.PropertyMembers.GivenPropertyMembersConjunction> and ArchUnitNET.Fluent.Syntax.Elements.Members.IMemberPredicates`1<ArchUnitNET.Fluent.Syntax.Elements.Members.PropertyMembers.GivenPropertyMembersConjunction> and ArchUnitNET.Fluent.Syntax.Elements.IObjectPredicates`1<ArchUnitNET.Fluent.Syntax.Elements.Members.PropertyMembers.GivenPropertyMembersConjunction> and ArchUnitNET.Fluent.Syntax.Elements.Members.IMemberPredicates`1<TGivenRuleTypeConjunction> and ArchUnitNET.Fluent.Syntax.Elements.IObjectPredicates`1<TGivenRuleTypeConjunction> and ArchUnitNET.Fluent.IHasDescription and ArchUnitNET.Fluent.IArchRuleCreator`1<ArchUnitNET.Domain.PropertyMember> and ArchUnitNET.Fluent.Syntax.Elements.Members.PropertyMembers.GivenPropertyMembersConjunction and ArchUnitNET.Fluent.Syntax.Elements.Members.PropertyMembers.PropertyMemberPredicateDefinition
    	ArchUnitNET.Fluent.Syntax.Elements.Members.PropertyMembers.IComplexPropertyMemberConditions does depend on ArchUnitNET.Fluent.Syntax.Elements.Members.IComplexMemberConditions`2<ArchUnitNET.Fluent.Syntax.Elements.Members.PropertyMembers.PropertyMembersShouldConjunction,ArchUnitNET.Domain.PropertyMember> and ArchUnitNET.Fluent.Syntax.Elements.IComplexObjectConditions`2<ArchUnitNET.Fluent.Syntax.Elements.Members.PropertyMembers.PropertyMembersShouldConjunction,ArchUnitNET.Domain.PropertyMember> and ArchUnitNET.Fluent.Syntax.Elements.IObjectConditions`1<ArchUnitNET.Fluent.Syntax.Elements.Members.PropertyMembers.PropertyMembersShouldConjunction> and ArchUnitNET.Fluent.Syntax.Elements.Members.IMemberConditions`1<ArchUnitNET.Fluent.Syntax.Elements.Members.PropertyMembers.PropertyMembersShouldConjunction> and ArchUnitNET.Fluent.Syntax.Elements.Members.PropertyMembers.IPropertyMemberConditions`1<ArchUnitNET.Fluent.Syntax.Elements.Members.PropertyMembers.PropertyMembersShouldConjunction>
    	ArchUnitNET.Fluent.Syntax.Elements.Members.PropertyMembers.IPropertyMemberConditions`1 does depend on ArchUnitNET.Fluent.Syntax.Elements.Members.IMemberConditions`1<TReturnType> and ArchUnitNET.Fluent.Syntax.Elements.IObjectConditions`1<TReturnType> and TReturnType
    	ArchUnitNET.Fluent.Syntax.Elements.Members.PropertyMembers.IPropertyMemberPredicates`1 does depend on ArchUnitNET.Fluent.Syntax.Elements.Members.IMemberPredicates`1<TRuleTypeConjunction> and ArchUnitNET.Fluent.Syntax.Elements.IObjectPredicates`1<TRuleTypeConjunction> and TRuleTypeConjunction
    	ArchUnitNET.Fluent.Syntax.Elements.Members.PropertyMembers.PropertyMemberConditionsDefinition does depend on System.Object and ArchUnitNET.Fluent.Conditions.ICondition`1<ArchUnitNET.Domain.PropertyMember> and ArchUnitNET.Fluent.Syntax.Elements.Members.PropertyMembers.PropertyMemberConditionsDefinition+<>c
    	ArchUnitNET.Fluent.Syntax.Elements.Members.PropertyMembers.PropertyMemberPredicateDefinition does depend on System.Object and ArchUnitNET.Fluent.Predicates.IPredicate`1<ArchUnitNET.Domain.PropertyMember> and ArchUnitNET.Fluent.Syntax.Elements.Members.PropertyMembers.PropertyMemberPredicateDefinition+<>c
    	ArchUnitNET.Fluent.Syntax.Elements.Members.PropertyMembers.PropertyMembersShould does depend on ArchUnitNET.Fluent.Syntax.Elements.Members.MembersShould`2<ArchUnitNET.Fluent.Syntax.Elements.Members.PropertyMembers.PropertyMembersShouldConjunction,ArchUnitNET.Domain.PropertyMember> and ArchUnitNET.Fluent.Syntax.Elements.Members.PropertyMembers.IComplexPropertyMemberConditions and ArchUnitNET.Fluent.Syntax.Elements.Members.IComplexMemberConditions`2<ArchUnitNET.Fluent.Syntax.Elements.Members.PropertyMembers.PropertyMembersShouldConjunction,ArchUnitNET.Domain.PropertyMember> and ArchUnitNET.Fluent.Syntax.Elements.IComplexObjectConditions`2<ArchUnitNET.Fluent.Syntax.Elements.Members.PropertyMembers.PropertyMembersShouldConjunction,ArchUnitNET.Domain.PropertyMember> and ArchUnitNET.Fluent.Syntax.Elements.IObjectConditions`1<ArchUnitNET.Fluent.Syntax.Elements.Members.PropertyMembers.PropertyMembersShouldConjunction> and ArchUnitNET.Fluent.Syntax.Elements.Members.IMemberConditions`1<ArchUnitNET.Fluent.Syntax.Elements.Members.PropertyMembers.PropertyMembersShouldConjunction> and ArchUnitNET.Fluent.Syntax.Elements.Members.PropertyMembers.IPropertyMemberConditions`1<ArchUnitNET.Fluent.Syntax.Elements.Members.PropertyMembers.PropertyMembersShouldConjunction> and ArchUnitNET.Fluent.Syntax.Elements.Members.IComplexMemberConditions`2<TRuleTypeShouldConjunction,TRuleType> and ArchUnitNET.Fluent.Syntax.Elements.IComplexObjectConditions`2<TRuleTypeShouldConjunction,TRuleType> and ArchUnitNET.Fluent.Syntax.Elements.IObjectConditions`1<TRuleTypeShouldConjunction> and ArchUnitNET.Fluent.Syntax.Elements.Members.IMemberConditions`1<TRuleTypeShouldConjunction> and ArchUnitNET.Fluent.IHasDescription and ArchUnitNET.Fluent.IArchRuleCreator`1<ArchUnitNET.Domain.PropertyMember> and ArchUnitNET.Fluent.Syntax.Elements.Members.PropertyMembers.PropertyMembersShouldConjunction and ArchUnitNET.Fluent.Syntax.Elements.Members.PropertyMembers.PropertyMemberConditionsDefinition
    	ArchUnitNET.Fluent.Syntax.Elements.Members.PropertyMembers.PropertyMembersShouldConjunction does depend on ArchUnitNET.Fluent.Syntax.Elements.ObjectsShouldConjunction`3<ArchUnitNET.Fluent.Syntax.Elements.Members.PropertyMembers.PropertyMembersShould,ArchUnitNET.Fluent.Syntax.Elements.Members.PropertyMembers.PropertyMembersShouldConjunctionWithDescription,ArchUnitNET.Domain.PropertyMember> and ArchUnitNET.Fluent.IArchRule and ArchUnitNET.Fluent.ICanBeEvaluated and ArchUnitNET.Fluent.IHasDescription and ArchUnitNET.Fluent.IArchRuleCreator`1<ArchUnitNET.Domain.PropertyMember>
    	ArchUnitNET.Fluent.Syntax.Elements.Members.PropertyMembers.PropertyMembersShouldConjunctionWithDescription does depend on ArchUnitNET.Fluent.Syntax.Elements.ObjectsShouldConjunctionWithDescription`2<ArchUnitNET.Fluent.Syntax.Elements.Members.PropertyMembers.PropertyMembersShould,ArchUnitNET.Domain.PropertyMember> and ArchUnitNET.Fluent.IArchRule and ArchUnitNET.Fluent.ICanBeEvaluated and ArchUnitNET.Fluent.IHasDescription and ArchUnitNET.Fluent.IArchRuleCreator`1<ArchUnitNET.Domain.PropertyMember>
    	ArchUnitNET.Fluent.Syntax.Elements.Members.PropertyMembers.ShouldRelateToPropertyMembersThat`2 does depend on ArchUnitNET.Fluent.Syntax.Elements.Members.ShouldRelateToMembersThat`3<TRuleTypeShouldConjunction,ArchUnitNET.Domain.PropertyMember,TRuleType> and ArchUnitNET.Fluent.Syntax.Elements.Members.PropertyMembers.IPropertyMemberPredicates`1<TRuleTypeShouldConjunction> and ArchUnitNET.Fluent.Syntax.Elements.Members.IMemberPredicates`1<TRuleTypeShouldConjunction> and ArchUnitNET.Fluent.Syntax.Elements.IObjectPredicates`1<TRuleTypeShouldConjunction> and ArchUnitNET.Fluent.IHasDescription and ArchUnitNET.Fluent.IArchRuleCreator`1<TRuleType> and TRuleTypeShouldConjunction and ArchUnitNET.Fluent.Syntax.Elements.Members.PropertyMembers.PropertyMemberPredicateDefinition and ArchUnitNET.Fluent.Syntax.ConjunctionFactory
    	ArchUnitNET.Fluent.Syntax.Elements.Members.MethodMembers.GivenMethodMembers does depend on ArchUnitNET.Fluent.Syntax.Elements.GivenObjects`3<ArchUnitNET.Fluent.Syntax.Elements.Members.MethodMembers.GivenMethodMembersThat,ArchUnitNET.Fluent.Syntax.Elements.Members.MethodMembers.MethodMembersShould,ArchUnitNET.Domain.MethodMember> and ArchUnitNET.Fluent.IObjectProvider`1<TRuleType> and ArchUnitNET.Fluent.IHasDescription and ArchUnitNET.Fluent.IArchRuleCreator`1<ArchUnitNET.Domain.MethodMember>
    	ArchUnitNET.Fluent.Syntax.Elements.Members.MethodMembers.GivenMethodMembersConjunction does depend on ArchUnitNET.Fluent.Syntax.Elements.GivenObjectsConjunction`4<ArchUnitNET.Fluent.Syntax.Elements.Members.MethodMembers.GivenMethodMembersThat,ArchUnitNET.Fluent.Syntax.Elements.Members.MethodMembers.MethodMembersShould,ArchUnitNET.Fluent.Syntax.Elements.Members.MethodMembers.GivenMethodMembersConjunctionWithDescription,ArchUnitNET.Domain.MethodMember> and ArchUnitNET.Fluent.IObjectProvider`1<TRuleType> and ArchUnitNET.Fluent.IHasDescription and ArchUnitNET.Fluent.IArchRuleCreator`1<ArchUnitNET.Domain.MethodMember>
    	ArchUnitNET.Fluent.Syntax.Elements.Members.MethodMembers.GivenMethodMembersConjunctionWithDescription does depend on ArchUnitNET.Fluent.Syntax.Elements.GivenObjectsConjunctionWithDescription`3<ArchUnitNET.Fluent.Syntax.Elements.Members.MethodMembers.GivenMethodMembersThat,ArchUnitNET.Fluent.Syntax.Elements.Members.MethodMembers.MethodMembersShould,ArchUnitNET.Domain.MethodMember> and ArchUnitNET.Fluent.IObjectProvider`1<TRuleType> and ArchUnitNET.Fluent.IHasDescription and ArchUnitNET.Fluent.IArchRuleCreator`1<ArchUnitNET.Domain.MethodMember>
    	ArchUnitNET.Fluent.Syntax.Elements.Members.MethodMembers.IComplexMethodMemberConditions does depend on ArchUnitNET.Fluent.Syntax.Elements.Members.IComplexMemberConditions`2<ArchUnitNET.Fluent.Syntax.Elements.Members.MethodMembers.MethodMembersShouldConjunction,ArchUnitNET.Domain.MethodMember> and ArchUnitNET.Fluent.Syntax.Elements.IComplexObjectConditions`2<ArchUnitNET.Fluent.Syntax.Elements.Members.MethodMembers.MethodMembersShouldConjunction,ArchUnitNET.Domain.MethodMember> and ArchUnitNET.Fluent.Syntax.Elements.IObjectConditions`1<ArchUnitNET.Fluent.Syntax.Elements.Members.MethodMembers.MethodMembersShouldConjunction> and ArchUnitNET.Fluent.Syntax.Elements.Members.IMemberConditions`1<ArchUnitNET.Fluent.Syntax.Elements.Members.MethodMembers.MethodMembersShouldConjunction> and ArchUnitNET.Fluent.Syntax.Elements.Members.MethodMembers.IMethodMemberConditions`1<ArchUnitNET.Fluent.Syntax.Elements.Members.MethodMembers.MethodMembersShouldConjunction>
    	ArchUnitNET.Fluent.Syntax.Elements.Members.MethodMembers.MethodMembersShouldConjunction does depend on ArchUnitNET.Fluent.Syntax.Elements.ObjectsShouldConjunction`3<ArchUnitNET.Fluent.Syntax.Elements.Members.MethodMembers.MethodMembersShould,ArchUnitNET.Fluent.Syntax.Elements.Members.MethodMembers.MethodMembersShouldConjunctionWithDescription,ArchUnitNET.Domain.MethodMember> and ArchUnitNET.Fluent.IArchRule and ArchUnitNET.Fluent.ICanBeEvaluated and ArchUnitNET.Fluent.IHasDescription and ArchUnitNET.Fluent.IArchRuleCreator`1<ArchUnitNET.Domain.MethodMember>
    	ArchUnitNET.Fluent.Syntax.Elements.Members.MethodMembers.MethodMembersShouldConjunctionWithDescription does depend on ArchUnitNET.Fluent.Syntax.Elements.ObjectsShouldConjunctionWithDescription`2<ArchUnitNET.Fluent.Syntax.Elements.Members.MethodMembers.MethodMembersShould,ArchUnitNET.Domain.MethodMember> and ArchUnitNET.Fluent.IArchRule and ArchUnitNET.Fluent.ICanBeEvaluated and ArchUnitNET.Fluent.IHasDescription and ArchUnitNET.Fluent.IArchRuleCreator`1<ArchUnitNET.Domain.MethodMember>
    	ArchUnitNET.Fluent.Syntax.Elements.Members.FieldMembers.FieldMembersShould does depend on ArchUnitNET.Fluent.Syntax.Elements.Members.MembersShould`2<ArchUnitNET.Fluent.Syntax.Elements.Members.FieldMembers.FieldMembersShouldConjunction,ArchUnitNET.Domain.FieldMember> and ArchUnitNET.Fluent.Syntax.Elements.Members.FieldMembers.IComplexFieldMemberConditions and ArchUnitNET.Fluent.Syntax.Elements.Members.IComplexMemberConditions`2<ArchUnitNET.Fluent.Syntax.Elements.Members.FieldMembers.FieldMembersShouldConjunction,ArchUnitNET.Domain.FieldMember> and ArchUnitNET.Fluent.Syntax.Elements.IComplexObjectConditions`2<ArchUnitNET.Fluent.Syntax.Elements.Members.FieldMembers.FieldMembersShouldConjunction,ArchUnitNET.Domain.FieldMember> and ArchUnitNET.Fluent.Syntax.Elements.IObjectConditions`1<ArchUnitNET.Fluent.Syntax.Elements.Members.FieldMembers.FieldMembersShouldConjunction> and ArchUnitNET.Fluent.Syntax.Elements.Members.IMemberConditions`1<ArchUnitNET.Fluent.Syntax.Elements.Members.FieldMembers.FieldMembersShouldConjunction> and ArchUnitNET.Fluent.Syntax.Elements.Members.FieldMembers.IFieldMemberConditions`1<ArchUnitNET.Fluent.Syntax.Elements.Members.FieldMembers.FieldMembersShouldConjunction> and ArchUnitNET.Fluent.Syntax.Elements.Members.IComplexMemberConditions`2<TRuleTypeShouldConjunction,TRuleType> and ArchUnitNET.Fluent.Syntax.Elements.IComplexObjectConditions`2<TRuleTypeShouldConjunction,TRuleType> and ArchUnitNET.Fluent.Syntax.Elements.IObjectConditions`1<TRuleTypeShouldConjunction> and ArchUnitNET.Fluent.Syntax.Elements.Members.IMemberConditions`1<TRuleTypeShouldConjunction> and ArchUnitNET.Fluent.IHasDescription and ArchUnitNET.Fluent.IArchRuleCreator`1<ArchUnitNET.Domain.FieldMember>
    	ArchUnitNET.Fluent.Syntax.Elements.Members.FieldMembers.FieldMembersShouldConjunction does depend on ArchUnitNET.Fluent.Syntax.Elements.ObjectsShouldConjunction`3<ArchUnitNET.Fluent.Syntax.Elements.Members.FieldMembers.FieldMembersShould,ArchUnitNET.Fluent.Syntax.Elements.Members.FieldMembers.FieldMembersShouldConjunctionWithDescription,ArchUnitNET.Domain.FieldMember> and ArchUnitNET.Fluent.IArchRule and ArchUnitNET.Fluent.ICanBeEvaluated and ArchUnitNET.Fluent.IHasDescription and ArchUnitNET.Fluent.IArchRuleCreator`1<ArchUnitNET.Domain.FieldMember>
    	ArchUnitNET.Fluent.Syntax.Elements.Members.FieldMembers.FieldMembersShouldConjunctionWithDescription does depend on ArchUnitNET.Fluent.Syntax.Elements.ObjectsShouldConjunctionWithDescription`2<ArchUnitNET.Fluent.Syntax.Elements.Members.FieldMembers.FieldMembersShould,ArchUnitNET.Domain.FieldMember> and ArchUnitNET.Fluent.IArchRule and ArchUnitNET.Fluent.ICanBeEvaluated and ArchUnitNET.Fluent.IHasDescription and ArchUnitNET.Fluent.IArchRuleCreator`1<ArchUnitNET.Domain.FieldMember>
    	ArchUnitNET.Fluent.Syntax.Elements.Members.FieldMembers.GivenFieldMembers does depend on ArchUnitNET.Fluent.Syntax.Elements.GivenObjects`3<ArchUnitNET.Fluent.Syntax.Elements.Members.FieldMembers.GivenFieldMembersThat,ArchUnitNET.Fluent.Syntax.Elements.Members.FieldMembers.FieldMembersShould,ArchUnitNET.Domain.FieldMember> and ArchUnitNET.Fluent.IObjectProvider`1<TRuleType> and ArchUnitNET.Fluent.IHasDescription and ArchUnitNET.Fluent.IArchRuleCreator`1<ArchUnitNET.Domain.FieldMember>
    	ArchUnitNET.Fluent.Syntax.Elements.Members.FieldMembers.GivenFieldMembersConjunction does depend on ArchUnitNET.Fluent.Syntax.Elements.GivenObjectsConjunction`4<ArchUnitNET.Fluent.Syntax.Elements.Members.FieldMembers.GivenFieldMembersThat,ArchUnitNET.Fluent.Syntax.Elements.Members.FieldMembers.FieldMembersShould,ArchUnitNET.Fluent.Syntax.Elements.Members.FieldMembers.GivenFieldMembersConjunctionWithDescription,ArchUnitNET.Domain.FieldMember> and ArchUnitNET.Fluent.IObjectProvider`1<TRuleType> and ArchUnitNET.Fluent.IHasDescription and ArchUnitNET.Fluent.IArchRuleCreator`1<ArchUnitNET.Domain.FieldMember>
    	ArchUnitNET.Fluent.Syntax.Elements.Members.FieldMembers.GivenFieldMembersConjunctionWithDescription does depend on ArchUnitNET.Fluent.Syntax.Elements.GivenObjectsConjunctionWithDescription`3<ArchUnitNET.Fluent.Syntax.Elements.Members.FieldMembers.GivenFieldMembersThat,ArchUnitNET.Fluent.Syntax.Elements.Members.FieldMembers.FieldMembersShould,ArchUnitNET.Domain.FieldMember> and ArchUnitNET.Fluent.IObjectProvider`1<TRuleType> and ArchUnitNET.Fluent.IHasDescription and ArchUnitNET.Fluent.IArchRuleCreator`1<ArchUnitNET.Domain.FieldMember>
    	ArchUnitNET.Fluent.Syntax.Elements.Members.FieldMembers.GivenFieldMembersThat does depend on ArchUnitNET.Fluent.Syntax.Elements.Members.GivenMembersThat`2<ArchUnitNET.Fluent.Syntax.Elements.Members.FieldMembers.GivenFieldMembersConjunction,ArchUnitNET.Domain.FieldMember> and ArchUnitNET.Fluent.Syntax.Elements.Members.FieldMembers.IFieldMemberPredicates`1<ArchUnitNET.Fluent.Syntax.Elements.Members.FieldMembers.GivenFieldMembersConjunction> and ArchUnitNET.Fluent.Syntax.Elements.Members.IMemberPredicates`1<ArchUnitNET.Fluent.Syntax.Elements.Members.FieldMembers.GivenFieldMembersConjunction> and ArchUnitNET.Fluent.Syntax.Elements.IObjectPredicates`1<ArchUnitNET.Fluent.Syntax.Elements.Members.FieldMembers.GivenFieldMembersConjunction> and ArchUnitNET.Fluent.Syntax.Elements.Members.IMemberPredicates`1<TGivenRuleTypeConjunction> and ArchUnitNET.Fluent.Syntax.Elements.IObjectPredicates`1<TGivenRuleTypeConjunction> and ArchUnitNET.Fluent.IHasDescription and ArchUnitNET.Fluent.IArchRuleCreator`1<ArchUnitNET.Domain.FieldMember>
    	ArchUnitNET.Fluent.Syntax.Elements.Members.FieldMembers.IComplexFieldMemberConditions does depend on ArchUnitNET.Fluent.Syntax.Elements.Members.IComplexMemberConditions`2<ArchUnitNET.Fluent.Syntax.Elements.Members.FieldMembers.FieldMembersShouldConjunction,ArchUnitNET.Domain.FieldMember> and ArchUnitNET.Fluent.Syntax.Elements.IComplexObjectConditions`2<ArchUnitNET.Fluent.Syntax.Elements.Members.FieldMembers.FieldMembersShouldConjunction,ArchUnitNET.Domain.FieldMember> and ArchUnitNET.Fluent.Syntax.Elements.IObjectConditions`1<ArchUnitNET.Fluent.Syntax.Elements.Members.FieldMembers.FieldMembersShouldConjunction> and ArchUnitNET.Fluent.Syntax.Elements.Members.IMemberConditions`1<ArchUnitNET.Fluent.Syntax.Elements.Members.FieldMembers.FieldMembersShouldConjunction> and ArchUnitNET.Fluent.Syntax.Elements.Members.FieldMembers.IFieldMemberConditions`1<ArchUnitNET.Fluent.Syntax.Elements.Members.FieldMembers.FieldMembersShouldConjunction>
    	ArchUnitNET.Fluent.Syntax.Elements.Members.FieldMembers.IFieldMemberConditions`1 does depend on ArchUnitNET.Fluent.Syntax.Elements.Members.IMemberConditions`1<TReturnType> and ArchUnitNET.Fluent.Syntax.Elements.IObjectConditions`1<TReturnType>
    	ArchUnitNET.Fluent.Syntax.Elements.Members.FieldMembers.IFieldMemberPredicates`1 does depend on ArchUnitNET.Fluent.Syntax.Elements.Members.IMemberPredicates`1<TRuleTypeConjunction> and ArchUnitNET.Fluent.Syntax.Elements.IObjectPredicates`1<TRuleTypeConjunction>
    	ArchUnitNET.Fluent.Syntax.Elements.Members.FieldMembers.ShouldRelateToFieldMembersThat`2 does depend on ArchUnitNET.Fluent.Syntax.Elements.Members.ShouldRelateToMembersThat`3<TRuleTypeShouldConjunction,ArchUnitNET.Domain.FieldMember,TRuleType> and ArchUnitNET.Fluent.Syntax.Elements.Members.FieldMembers.IFieldMemberPredicates`1<TRuleTypeShouldConjunction> and ArchUnitNET.Fluent.Syntax.Elements.Members.IMemberPredicates`1<TRuleTypeShouldConjunction> and ArchUnitNET.Fluent.Syntax.Elements.IObjectPredicates`1<TRuleTypeShouldConjunction> and ArchUnitNET.Fluent.IHasDescription and ArchUnitNET.Fluent.IArchRuleCreator`1<TRuleType>
    	ArchUnitNET.Fluent.Extensions.EnumerableExtensions does depend on System.Object and System.Runtime.CompilerServices.ExtensionAttribute and System.Collections.Generic.IEnumerable`1<ArchUnitNET.Domain.Slice`1<System.String>> and System.Collections.Generic.IEnumerable`1<ArchUnitNET.Domain.IType> and System.String and ArchUnitNET.Fluent.Extensions.EnumerableExtensions+<>c and System.Collections.Generic.IEnumerable`1<ArchUnitNET.Fluent.EvaluationResult> and System.Collections.Generic.List`1<ArchUnitNET.Fluent.EvaluationResult> and System.Text.StringBuilder and System.Collections.Generic.IEnumerator`1<ArchUnitNET.Fluent.ICanBeEvaluated> and ArchUnitNET.Fluent.Extensions.EnumerableExtensions+<>c__DisplayClass6_0 and System.Collections.Generic.IEnumerator`1<ArchUnitNET.Fluent.EvaluationResult> and System.Func`2<ArchUnitNET.Fluent.EvaluationResult,System.Boolean> and ArchUnitNET.Fluent.EvaluationResult and ArchUnitNET.Fluent.Extensions.EnumerableExtensions and ArchUnitNET.Fluent.IHasDescription
    	ArchUnitNET.Fluent.Extensions.InstructionExtensions does depend on System.Object and System.Runtime.CompilerServices.ExtensionAttribute and System.Boolean and Mono.Cecil.Cil.Instruction and ArchUnitNET.Fluent.Extensions.InstructionExtensions and Mono.Cecil.FieldDefinition and Mono.Cecil.FieldReference and ArchUnitNET.Fluent.Extensions.MonoCecilMemberExtensions
    	ArchUnitNET.Fluent.Extensions.NullableExtensions does depend on System.Object and System.Runtime.CompilerServices.ExtensionAttribute
    	ArchUnitNET.Fluent.Extensions.RegexUtils does depend on System.Object and System.Text.RegularExpressions.Regex and System.String and System.Text.RegularExpressions.Match and System.Boolean
    	ArchUnitNET.Fluent.Extensions.StaticConstants does depend on System.Object and System.String
    	ArchUnitNET.Fluent.Extensions.SyntaxElementExtensions does depend on System.Object and System.Runtime.CompilerServices.ExtensionAttribute and System.String and ArchUnitNET.Fluent.IHasDescription and System.Int32
    	ArchUnitNET.Fluent.Exceptions.CannotGetObjectsOfCombinedArchRuleCreatorException does depend on System.Exception and System.Runtime.Serialization.ISerializable and System.String
    	ArchUnitNET.Fluent.Exceptions.CannotGetObjectsOfCombinedArchRuleException does depend on System.Exception and System.Runtime.Serialization.ISerializable and System.String
    	ArchUnitNET.Fluent.Conditions.RelationCondition`2 does depend on System.Object and ArchUnitNET.Fluent.IHasDescription and System.Func`2<System.Collections.Generic.IEnumerable`1<TRelatedType>,ArchUnitNET.Fluent.Conditions.ICondition`1<TRuleType>> and System.String and System.Runtime.CompilerServices.CompilerGeneratedAttribute and ArchUnitNET.Fluent.Conditions.ICondition`1<TRuleType> and System.Collections.Generic.IEnumerable`1<TRelatedType> and System.Boolean and ArchUnitNET.Fluent.Conditions.RelationCondition`2<TRuleType,TRelatedType> and System.Int32

Feature Request: PlantUML Support

Similar as in original ArchUnit the PlantUML support is long awaited and would help on improving the relationship between documentation and code.

Before I start some development I would like to start some discussions here, because I saw a fork from @studix who worked on this for some time.

Package installation fails in .NET Framework 4.6.1, .NET Core environment.

Hello, I was interested in ArchUnitNET to improve the quality of my project's architecture.
But, Now I can't installed in .NET Framework 4.6.1, .NET Core development environments.

Of course the .NET Framework 4.6.1 version is not the latest, But My personal project is currently using version 4.6.1.
If you care about supporting this issue, I'm sure more developers will be able to help improve software quality through this library.

I hope you can apply for the issue.
Thank you!

Classes contain structs

I would expect this test not to fail in a code base with classes and structs.
It would be nice to have Structs separately.

using ArchUnitNET.Fluent;
using ArchUnitNET.NUnit;
using NUnit.Framework;
using static ArchUnitNET.Fluent.ArchRuleDefinition;

namespace PostSolutionTests
{
    class ClassesShouldNotBeStructs
    {
        private static readonly IArchRule ClassesShouldNotBeStructsRule = Classes().Should().NotBeStructs();

        [Test, Category("ArchUnitTest")]
        public static void ClassesShouldNotBeStructsTests() => ClassesShouldNotBeStructsRule.Check(Architecture.Dialux);
    }
}

Tests are always passing in latest 0.10+nuget package

I have test:

using static ArchUnitNET.Fluent.ArchRuleDefinition;
    [Fact]
    public void EntityFrameworkCore_ShouldOnlyResideInInfrastructure_WhenEntityFrameworkCoreIsUsed()
    {
        IArchRule validatorNamingConventionRule = Classes().That()
            .DependOnAny("Microsoft.EntityFrameworkCore").And().DoNotResideInNamespace("Microsoft.Extensions.DependencyInjection")
            .Should()
            .NotResideInNamespace("Infrastructure.Data.EntityFramework");

        validatorNamingConventionRule.Check(Architecture);
    }

That is properly failing in version 0.9.1 but passing in version 0.10+

Slice names have only the dynamic part

I want to create a plantuml diagram based on found errors, eg.

            IArchRule noCycles = SliceRuleDefinition.Slices().Matching("ArchUnitNET.(*)").Should().BeFreeOfCycles();
            noCycles.Check(Architecture);

but the found slices are all without the "ArchUnitNet." prefix (e.g. "Fluent", but I would expect "ArchUnitNET.Fluent").
Is it possible to add a "full name" property to the slices with the fix parts too?

Thank you and best regards
Helmut

PS.: Atm I use C4-PlantUML but maybe I can extend add a better namesspaces/classes diagram too

simple

detailed

With correct Namespace it could look like
correct namespace

Error message does not list offending dependencies

Hi,

have a rule like:

var a2 = Types()
                .That()
                .ResideInNamespace("DataAccessModel")
                .Should()
                .NotDependOnAnyTypesThat().AreAssignableTo(typeof(DataBase))
                .As("that would not be nice");

The issue is that the error message lists the whole dependencies of the offending type, not just the offending dependencies.

ArchUnitNET.xUnit.FailedArchRuleException
"Classes that are db access model should not depend on any types that are comm layer" failed:
DSP does depend on E and V and ... (redacted to protect the innocent).

Even just the first offending dependency would be a lot more helpful.

How to find and verify nested types for a given type?

In my current project I have the following requirement:

There are certain classes (representing commands) that should be validated. The validator for each command should be contained in a nested class within that command and implement FluentValidation.IValidator.
The example command class should thus look like this:

public class MyCommand : ICommand
{
    // some properties
    
    public class Validator : AbstractValidator<MyCommand>
    {
        // definitions of validation rules
    }
}

So the way to go should probably be like this:

  1. load up the assembly into ArchLoader
  2. filter all the relevant classes (in this case, classes that implement ICommand interface)
  3. for each filtered class get its nested classes
  4. check that for each filtered class at least one nested class satisfies some predicate

Checking whether a given type is nested is pretty simple, but I can't find a way to easily obtain any information about the relationship between nesting and nested types (both from nested and nesting type's perspective), and thus I'm stuck on step 3.

I've thrown together a query that extracts all the commands and their potential validators by joining them on IType.FullName (using MoreLINQ's LeftJoin, example below), but that's much less intuitive and requires much more work than simply querying a type for its nested types. Is there a way to get this kind of information without resorting to such hacks?

[Fact]
public void All_commands_must_have_validators()
{
    static string ExtractValidatedClass(Class validatorClass)
    {
        if (validatorClass.IsNested)
            return validatorClass.FullName.Substring(0, validatorClass.FullName.LastIndexOf("+"));
        else
            return null;
    }


    var architecture = new ArchLoader().LoadAssemblies(
            typeof(MyProject.MarkerInterface).Assembly,
            typeof(FluentValidation.IValidator).Assembly)
        .Build();
        
    var commandType = architecture.GetInterfaceOfType(typeof(ICommmand));
    var validatorType = architecture.GetInterfaceOfType(typeof(FluentValidation.IValidator));

    var commands = architecture.Classes.Where(x => x.IsAssignableTo(commandType));
    var validators = architecture.Classes.Where(x => x.IsAssignableTo(validatorType));

    var commandsAndValidators = commands.LeftJoin(validators,
        command => command.FullName,
        validator => ExtractValidatedClassName(validator),
        command => new { command, validator = (Class?)null },
        (command, validator) => new { command, validator })
        .ToList();

    commandsAndValidators.Should().AllSatisfy(x => x.validator.Should().NotBeNull());
}

Is ExampleArchUnitTestCooking test working for .Net Core SDK(3.1.101)

I am very excited about this great. framework . Great work
I have a question .
Is ExampleArchUnitTestCooking working for .Net Core SDK(3.1.101).

I removed the ICook interface from FrenchChef and ran the test.
Test is still passing. I was expecting it to fail
Looking forward to your answer.

Nested Types (only one level)

I have some classes like this because this is a pattern we use in our codebases for various good reasons:

    public static class Events
    {
        public static class Thing
        {
            public class CreateThing : IChangeEvent
            {
                public string EntityId { get; set; }

                public DateTime ModifiedUtc { get; set; }
            }
        }
    }

Now, I want to capture all the classes that derive from the interface IChangeEvent but as it turns out, I never see any.

This statement captures the Thing class, but not the CreateThing class.

var classes = ArchRuleDefinition.Types(true).That().ResideInNamespace("MyNamespace", true);

The framework seems to support nested classes, but it only seems to support one level of nesting.

So this does not work either:

var classes = ArchRuleDefinition.Types(true).That().ResideInNamespace("MyNamespace", true).And().AreNested();

How can I capture my deeper nested classes, no matter how nested they are?
(max 3 levels is probably all we need in practice)

Check that Properties only return certain types

Is there a way to assert that the public getter/setter properties of all types in a namespace, only return values of a set of given types (eg. string)?

for example: this class should fail on PropertyB.

public class MyClass
{
    public string PropertyA { get; set; }
    public long PropertyB { get; set; }
}

Can you give an example of how?

Generic Methods with two generic paramters

Hello!

I found bug probably. When I tried Build Architecture using ArchLoader with Build method I have exception:

System.InvalidOperationException : Full name of declaring member doesn't match. at ArchUnitNET.Domain.GenericParameter.AssignDeclarer(IMember declaringMethod) at ArchUnitNET.Loader.LoadTasks.AddGenericParameterDependencies.AddMemberGenericParameterDependencies() at ArchUnitNET.Loader.LoadTasks.AddGenericParameterDependencies.Execute() at ArchUnitNET.Loader.LoadTaskRegistry.<ExecuteTasks>b__1_1(Type taskKey) at ArchUnitNET.Domain.Extensions.EnumerableExtensions.ForEach[T](IEnumerable1 source, Action1 action) at ArchUnitNET.Loader.LoadTaskRegistry.ExecuteTasks(List1 taskOrder)
at ArchUnitNET.Loader.ArchBuilder.UpdateTypeDefinitions()
at ArchUnitNET.Loader.ArchBuilder.Build()
at ArchUnitNET.Loader.ArchLoader.Build()`

I little investigated it and I think the proble is with overloaded generic methods. See screenshots.

How can I handle with this case? Should wait for fix, or you have some workaround how can I build architecture with generic overloaded methods.

thank you in advance!

Have a good day!
test

Handle projects using nullable reference types

Background

Create a class that uses the nullable reference type feature:

#nullable enable

namespace TestAssembly
{
    public class ClassUsingNullableReferenceType
    {
        public string? Name { get; set; }
    }
}

#nullable disable

Create a rule that verifies that the class just depends on itself:

[Fact]
public void ClassUsingNullableReferenceTypeShouldDependOnlyOnItself()
{
    var classUsingNullableReferenceType = Types().That().Are(typeof(ClassUsingNullableReferenceType));

    var classDependsOnlyOnItself = classUsingNullableReferenceType.Should().OnlyDependOn(classUsingNullableReferenceType);

    classDependsOnlyOnItself.Check(Architecture);
}

Expected result

Rule passes.

Actual result

Rule fails.

Reason

When using the nullable reference type feature the compiler adds some attributes to the assembly:

Microsoft.CodeAnalysis.EmbeddedAttribute
System.Runtime.CompilerServices.NullableAttribute
System.Runtime.CompilerServices.NullableContextAttribute

These attributes are added to the types of the architecture which makes the rule fail.

Solution

Filter the attributes while building the architecture.
ArchBuilder.cs

public void LoadTypesForModule(ModuleDefinition module, string namespaceFilter)
{
    _architectureCacheKey.Add(module.Name, namespaceFilter);

    var types = module.Types.First().FullName.Contains("<Module>")
        ? module.Types.Skip(1).ToList()
        : module.Types.ToList();

    types = types.Where(t => t.FullName != "Microsoft.CodeAnalysis.EmbeddedAttribute" &&
		t.FullName != "System.Runtime.CompilerServices.NullableAttribute" &&
		t.FullName != "System.Runtime.CompilerServices.NullableContextAttribute").ToList();
...

Inspecting attributes

Right now, ArchUnitNET allows us to test whether our classes are decorated with certain attributes (via either Classes().Should().HaveAnyAttributes(typeof(MyAttribute)) or Class.HasAttribute("MyAttribute"). However, in most cases it's not only the presence of an attribute that is important, but also its properties (or its value, which is just a special case of a single property).

For example, in my current project I have a requirement that not only all the event classes should be marked with a EventDefinition attribute, but also that this attribute should define a name conforming to some domain-specific rules. So basically all the event classes should look like this:

public namespace MyModule
{
    [EventDefinition(Name = "MyModule.EmailSentEvent")]
    public class EmailSentEvent : IEvent
    {
        // some event data
    }
}

Unfortunately, ArchUnitNET doesn't seem to provide any way to inspect the properties of an attribute. There's neither out-of-the-box method that checks the value of an attrubite, nor the built-in properties and extension methods on ArchUnitNET.Domain.Attribute seem to offer any way of inspecting those properties. They seem to be concerned mainly with the attribute type itself, while it's an attribute instance that is bound to a class and needs to be inspected.

So, how can I inspect the properties of an attribute that a certain class is decorated with? Am I missing something, or there's currently no way to do this in ArchUnitNET?

AreAssignableTo is extremely slow.

Hello.

I have a problem with performance AreAssignableTo method. Example Code below:

`public class DomainDependenciesTests
{
private Architecture _architecture;
private GivenClassesConjunction _entitiesClasses;

    [OneTimeSetUp]
    public void LoadAssemblies()
    {
        _architecture = new ArchLoader()
            .LoadAssemblies(Assembly.Load("xx.xxx.xxx"))
            .Build();

        _entitiesClasses = Classes().That().AreAssignableTo(typeof(EntityBase));
    }

    [Test]
    public void Entities_CheckAllAssignableToEntityBase_ShouldAllNotContainingDependenciesToRepositoriesAndEventsAndServices()
    {
        var forbiddenTypes = Types().That().AreAssignableTo(typeof(RepositoryBase))
            .Or().ImplementInterface(typeof(IEvent))
            .Or().HaveFullNameContaining("Service");

        // var testEntities = _entitiesClasses.GetObjects(_architecture).ToList(); --> return >400 classes time: a few min. ~3min
        // var testAllowedTypes = forbiddenTypes.GetObjects(_architecture).ToList(); --> return > 1200 types ~5min

        var entitiesOnlyDependOnDomain = _entitiesClasses.Should().NotDependOnAny(forbiddenTypes);
        var result = entitiesOnlyDependOnDomain.Evaluate(_architecture); // --> nevending story more than 10min
        result.Should().AllPassed();
    }
}`

I know it will be hard to reproduce without my project, but maybe you know about some problem of performance in your sides? Or maybe you can see, what I doing wrong. I didn't see perf problem before but I usually used methods based on Namespace.

Thank you in advance. Have a good day!

System.InvalidCastException

Hello!

I have problem with loading assemblies. This is my code:
public void LoadAssemblies() { _architecture = new ArchLoader() .LoadAssemblies(typeof(Sm.Aspen.Domain.IAssemblyMarker).Assembly, typeof(Sm.Aspen.Messages.IAssemblyMarker).Assembly) .Build(); }

and this part of code throwing exception:
OneTimeSetUp: System.InvalidCastException : Unable to cast object of type 'ArchUnitNET.Loader.TypeInstance1[ArchUnitNET.Domain.Class]' to type 'ArchUnitNET.Domain.ITypeInstance1[ArchUnitNET.Domain.Interface]'.

please let me know if it bug or I do something wrong.

Thank you in advance.
Have a nice day!

PUML Errormesasages contains multiple duplications

The errormessages you get when the architecture in your code does not match the architecture of the Puml does contain many duplications.
Duplications are filtered in the non-puml version, but not in puml.
For example:
I get the errormessage:

"Types should adhere to PlantUML diagram." failed:
ExampleTest.PlantUml.Products.Product does depend on ExampleTest.PlantUml.Customers.Customer
ExampleTest.PlantUml.Orders.Order does depend on ExampleTest.PlantUml.Products.Product and ExampleTest.PlantUml.Products.Product and ExampleTest.PlantUml.Products.Product and ExampleTest.PlantUml.Products.Product and ExampleTest.PlantUml.Products.Product and ExampleTest.PlantUml.Products.Product and ExampleTest.PlantUml.Products.Product and ExampleTest.PlantUml.Products.Product and ExampleTest.PlantUml.Products.Product and ExampleTest.PlantUml.Addresses.Address and ExampleTest.PlantUml.Products.Product
ExampleTest.PlantUml.Importer.ProductImport does depend on ExampleTest.PlantUml.Customers.Customer and ExampleTest.PlantUml.Customers.Customer and ExampleTest.PlantUml.Customers.Customer and ExampleTest.PlantUml.Customers.Customer and ExampleTest.PlantUml.Customers.Customer and ExampleTest.PlantUml.Customers.Customer and ExampleTest.PlantUml.Customers.Customer
ExampleTest.PlantUml.Customers.Customer does depend on ExampleTest.PlantUml.Addresses.Address and ExampleTest.PlantUml.Addresses.Address and ExampleTest.PlantUml.Addresses.Address and ExampleTest.PlantUml.Addresses.Address and ExampleTest.PlantUml.Addresses.Address and ExampleTest.PlantUml.Orders.Order
ExampleTest.PlantUml.Catalog.ProductCatalog does depend on ExampleTest.PlantUml.Customers.Customer and ExampleTest.PlantUml.Orders.Order and ExampleTest.PlantUml.Orders.Order and ExampleTest.PlantUml.Orders.Order and ExampleTest.PlantUml.Customers.Customer
ExampleTest.PlantUml.Addresses.Address does depend on ExampleTest.PlantUml.Catalog.ProductCatalog

which can be shorten without duplications to:

"Types should adhere to PlantUML diagram." failed:
ExampleTest.PlantUml.Products.Product does depend on ExampleTest.PlantUml.Customers.Customer
ExampleTest.PlantUml.Orders.Order does depend on ExampleTest.PlantUml.Products.Product and ExampleTest.PlantUml.Addresses.Address
ExampleTest.PlantUml.Importer.ProductImport does depend on ExampleTest.PlantUml.Customers.Customer
ExampleTest.PlantUml.Customers.Customer does depend on ExampleTest.PlantUml.Addresses.Address and ExampleTest.PlantUml.Orders.Order
ExampleTest.PlantUml.Catalog.ProductCatalog does depend on ExampleTest.PlantUml.Customers.Customer and ExampleTest.PlantUml.Orders.Order
ExampleTest.PlantUml.Addresses.Address does depend on ExampleTest.PlantUml.Catalog.ProductCatalog

Generics not recognized properly

Not sure if this is intended or not but I'm unable to get generics types recognized properly.

I want to enforce that all logger members are of type ILogger<> but I can't get it working my method :

        IArchRule rule =
            FieldMembers().That().HaveName("logger")
            .Should().Be(Types().That().Are(typeof(ILogger<>)))
            .AndShould().BePrivate();
        rule.Check(architecture);

I have also tried

        IArchRule rule =
            FieldMembers().That().HaveName("logger")
            .Should().Be(Interfaces().That().HaveFullNameContaining("Microsoft.Extensions.Logging.ILogger"))
            .AndShould().BePrivate();
        rule.Check(architecture);

to no avail, each time I get a list of my types with :

Message:โ€‰
Assert.Fail failed. "Field members that have name "logger" should be Interfaces that are "Microsoft.Extensions.Logging.ILogger1" and should be private" failed: Microsoft.Extensions.Logging.ILogger1<CotisationsWS.DAL.OracleAppelRepository> CotisationsWS.DAL.OracleAppelRepository::logger is not Interfaces that are "Microsoft.Extensions.Logging.ILogger`1"
[...]

HaveReturnType() does not support generic types

Hi,

I encountered an issue using the HaveReturnType("...") check.
Methods that return generic types fail to match.
Used example :

MethodMembers().That().AreDeclaredIn(Controllers())
    .And().ArePublic()
    .And().AreNoConstructors()
    .Should().HaveReturnType(typeof(Task<IActionResult>))
    .Check(Architecture);

If I replace usage with .HaveReturnType(typeof(Task<>)), it woks fine, but not usefull in this case :-)

LoadAssembliesIncludingDependencies fails for record type

Hi, I have a problem when using the LoadAssembliesIncludingDependencies method with the record types introduced in C#9.
The problem occured when migrating old classes to record types.
Suddenly I was getting NullReferenceExceptions in my unit tests (stacktrace at the end of the issue).

I tried to narrow it down and the trigger for the exception seems to be a method inside my new record type:

public ProductIdentityBase CopyWithNewName(string name)
{
    return this with { Name = name };
}

I wanted to keep the old method signatures for creating copies of my classes.

I created a minimal example in my github to reproduce the issue, feel free to check it out:
https://github.com/mw-ste/ArchUnitNetRecordTypes

Stack trace:

System.NullReferenceException
Object reference not set to an instance of an object.
   at ArchUnitNET.Loader.LoadTasks.AddMethodDependencies.CreateMethodBodyDependenciesRecursive(MethodBody methodBody, ICollection`1 visitedMethodReferences, List`1 bodyTypes, List`1 castTypes, List`1 typeCheckTypes, List`1 metaDataTypes, List`1 accessedFieldMembers)+MoveNext()
   at ArchUnitNET.Loader.LoadTasks.AddMethodDependencies.CreateMethodBodyDependenciesRecursive(MethodBody methodBody, ICollection`1 visitedMethodReferences, List`1 bodyTypes, List`1 castTypes, List`1 typeCheckTypes, List`1 metaDataTypes, List`1 accessedFieldMembers)+MoveNext()
   at System.Linq.Enumerable.WhereEnumerableIterator`1.MoveNext()
   at System.Linq.Enumerable.DistinctIterator`1.MoveNext()
   at ArchUnitNET.Loader.LoadTasks.AddMethodDependencies.CreateMethodBodyDependencies(MethodDefinition methodDefinition, MethodMember methodMember)+MoveNext()
   at System.Linq.Enumerable.ConcatIterator`1.MoveNext()
   at System.Collections.Generic.List`1.InsertRange(Int32 index, IEnumerable`1 collection)
   at System.Collections.Generic.List`1.AddRange(IEnumerable`1 collection)
   at ArchUnitNET.Loader.LoadTasks.AddMethodDependencies.<>c.<Execute>b__4_3(ValueTuple`2 tuple)
   at ArchUnitNET.Domain.Extensions.EnumerableExtensions.ForEach[T](IEnumerable`1 source, Action`1 action)
   at ArchUnitNET.Loader.LoadTasks.AddMethodDependencies.Execute()
   at ArchUnitNET.Loader.LoadTaskRegistry.<ExecuteTasks>b__1_1(Type taskKey)
   at ArchUnitNET.Domain.Extensions.EnumerableExtensions.ForEach[T](IEnumerable`1 source, Action`1 action)
   at ArchUnitNET.Loader.LoadTaskRegistry.ExecuteTasks(List`1 taskOrder)
   at ArchUnitNET.Loader.ArchBuilder.UpdateTypeDefinitions()
   at ArchUnitNET.Loader.ArchBuilder.Build()
   at ArchUnitNET.Loader.ArchLoader.Build()
   at ArchUnitNetRecordTypes.Should.ArchUnitNetRecordShould.WorkWithRecordTypes() in E:\ArchUnitNetRecordTypes\ArchUnitNetRecordTypes.Should\ArchUnitNetRecordShould.cs:line 13

Assemblies as a Syntax element

It would be nice to be able to write Rules like
Assemblies().That().Rererence(...)

You can do that with types but then you can have the assembly reference and the test will not fail if no type is used.

private static bool IsInTestAssembly(IType type) => type.Assembly.Attributes.Any(a => a.Name == nameof(TestAssemblyAttribute));

private static IObjectProvider<IType> TypesResidingingInTestAssemblies = Types().That().FollowCustomPredicate(IsInTestAssembly, "Are in test assembly.");

Create a naming rule for a simple generic class

Hello. After playing around for simple naming rules I got to a point I don't know how to write it.

Below you can see a class model of the CQRS-pattern. Simple naming rules I got on my own. But know I want to write a rule which check the prefix of the "Handler"-class.

The rule should be:
Handler naming must match the name of the request (first generic argument) except their own naming suffix (-Handler, and -Response).

public class MyOwnRequest : IRequest<MyOwnResponse>
{
}

public class MyOwnResponse : IResponse
{
}

// The name of this handler must have the prefix 'MyOwn' because the first generic arg (request) has it.
public class MyOwnHandler : IHandler<MyOwnRequest, MyOwnResponse>
{
}

Can we add an overload with assembly filter support to ArchLoader?

Hello! First of all, thank you for the library, it has been really helpful ๐Ÿ˜ƒ

I'd like to suggest adding another overload to ArchLoader class to support custom user-defined filters for loading assemblies.
Basically, what I want to do is to define small set of "entrypoint" assemblies and load their dependencies recursively, but load only assemblies that I own (I can easily choose them by common name prefix we use).
With current overloads I either have to list all required assemblies directly (which is bad because we certainly will add new ones in the future), or use several invocations of LoadDirectory with specific hard-coded paths which is also quite brittle.

I think this overload should look something like this LoadAssemblies(params System.Reflection.Assembly[] assemblies, bool includingDependencies, bool recursive, Func<ModuleDefinition, bool> predicate). If you're ok with this change, I will submit a PR.

ResideInNamespace contains instead of exact

Turns out that the rule ResideInNamespace("anamespace", false) does a partial match on the namespace instead of a full match, and so extra types are captured from other namespaces that should not be, and this makes no sense logically.

For example: I have assemblies with these namespaces:
Api.Interfaces and External.Api.Interfaces.

If use this rule:

var responseDtos = ArchRuleDefinition.Types(true).That().ArePublic().As("Things")
                .And().ResideInNamespace("Api.Interfaces")

I process types that are in both the Api.Interfaces and External.Api.Interfaces namespaces, which is not what I would expect at all.

Looking at the code, it appears that ResideInNamespace calls NamingExtensions.FullNameContains which does a partial match on the namespace.

Building Assemblies failed

Hello, I tried to use ArchUnitNET (v0.4.3, .NET Framework 4.6.1 ) But When Building assemblies , exception was occured.
Is Any wrong with this code? or is it a bug?
Thank you for your help.

Code :

[TestClass]
    public class DependencyTests
    {
        private static readonly string clientNamespace = typeof(clientClass).Namespace;
        private static readonly string serverNamespace = typeof(serverClass).Namespace;
        private static readonly Architecture _architecture = new ArchLoader().LoadAssemblies(typeof(clientClass).Assembly, typeof(serverClass).Assembly).Build(); //Error

        [TestMethod]
        public void TestMethod1()
        {            
            IArchRule rule = Types().That().ResideInNamespace(clientNamespace).Should()
                    .NotDependOnAny(Types().That().ResideInNamespace(serverNamespace));

            Assert.IsTrue(rule.HasNoViolations(_architecture));
        }
    }

Exception :
Cannot cast type object'ArchUnitNET.Loader.TypeInstance1[ArchUnitNET.Domain.Class]' to type'ArchUnitNET.Domain.ITypeInstance1[ArchUnitNET.Domain.Interface]'.

Location: ArchUnitNET.Loader.LoadTasks.AddClassDependencies. b__7_0 (TypeReference target)
Location: ArchUnitNET.Domain.Extensions.EnumerableExtensions.ForEach [T] (IEnumerable1 source, Action1 action)
Location: ArchUnitNET.Loader.LoadTasks.AddClassDependencies.AddInterfaceDependencies()
Location: ArchUnitNET.Loader.LoadTasks.AddClassDependencies.Execute()
Location: ArchUnitNET.Loader.LoadTaskRegistry. b__1_1 (type taskKey)
Location: ArchUnitNET.Domain.Extensions.EnumerableExtensions.ForEach [T] (IEnumerable1 source, Action1 action)
Location: ArchUnitNET.Loader.LoadTaskRegistry.ExecuteTasks (List`1 taskOrder)
Location: ArchUnitNET.Loader.ArchBuilder.UpdateTypeDefinitions()
Location: ArchUnitNET.Loader.ArchBuilder.Build()
Location: ArchUnitNET.Loader.ArchLoader.Build()
Location: DependencyTests.TestMethod1() File

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.