Search code examples
c#.netumlroslynroslyn-code-analysis

C# Roslyn - get dependency type out of INamedTypeSymbol


I am trying to find a good solution to finding out whether a dependency on another class in C# is in composition or agreggation.

Is there a better way to do it than like this?

private static DependencyType GetDependencyAssociation(this INamedTypeSymbol? symbol)
{
    if (symbol.IsReferenceType && !symbol.IsValueType)
    {
        return DependencyType.Aggregation;
    }

    if (symbol.IsReferenceType && symbol.IsValueType)
    {
        return DependencyType.Composition;
    }
    
    return DependencyType.Association;
}

Solution

  • From the code snippet, it is not clear how you get the dependency and why you are sure that the dependency is an a kind of association.

    Not all dependencies imply associations

    First of all, there are many dependencies that do not necesarily imply an association:

    • Take for example the factory pattern, where the factory type F has a «create» dependency to the type T it is supposed to instantiate. The fact that a factory object creates object of type T does not at all imply that there will be a structural/semantic relation between the factory object and the created object. In most factory implementations, there isn't.
    • Another example is when a type A has an operation that uses a parameter of type B. There is a use dependency from A to B. There again statements like Console. WriteLine(object) does not at all imp'y that the console and the object will be associated!

    If you are sure that the dependcy is related to an association, for example if type X has a property of type Y, of a property that is a container of type Z, then your code snippet make sense.

    your snippet will not work as you think

    I'm not a Roselyn expert, but from the documentation of INamedTypeSymbol we can see that IsReferenceType and IsValueType are mutually exclusive: at most one of the two is true:

    It is never the case that IsReferenceType and IsValueType both return true. However, for an unconstrained type parameter, IsReferenceType and IsValueType will both return false.

    The first if can therefore be simplified into if (symbol.IsReferenceType). The second if will newer be fired as its condition will always be wrong.

    Revised algorithm

    Assuming you capture well candidate associations, for example that for a type A you have a property of type B:

    • if symbol B is a reference type, there is an association.
    • if the symbol B is a value type (e.g. a struct embedded in a class, according to C# semantics) then there is a composition since the B object is created with the A object and will be destroyed with the A object.

    But what's with aggregation? You don't need it! because the UML specifications do not define any semantics for it. The specs leave the possibility for a group of modelers to define their own semantics. Moreover even if there were some semantics agreed, how could you objectively verify a very conceptual criteria in your code?