views:

69

answers:

3

Given a sequence of assemblies with classes eg.

  AssemblyA
    Customer
  AssemblyB
    Customer : AssemblyA.Customer
  AssemblyC
    Customer : AssemblyB.Customer

Given the name (not taken care of namespace) Customer, can I use LINQ to query against the sequence of assemblies to find the customer at the bottom of the inheritance chain (AssemblyC.Customer in this case) ?

A: 

This tool might help you:

http://www.red-gate.com/products/reflector/

TimS
Well, thats not gonna help me here, I have knowledge about the structure of all assemblies, I even have the source :)
Marcus
A: 

The first question is how to determine the assemblies to be searched. System.Reflection.Assembly provides a number of methods for listing certain types of assemblies - for example GetReferencedAssemblies() will find assemblies referenced by a given assembly - useful if you have Assembly C (which refernces B and A), but not if you just have Assembly A (which references none). You could also scan the disk, or other methods, depending on your needs.

Once you've determined how to iterate assemblies, use the technique from this item to find classes that derive from the class in question: http://stackoverflow.com/questions/2362580/discovering-derived-types-using-reflection

Apply this logic recursively until you reach the end of the tree. The commenter on your question is right - the tree may have multiple branches.

I do not know why you'd want to use Linq to do this - Linq does not seem built for this type of question. I have not personally found a way to do recursion or queue-based operations well inside of Linq. I'd just use C# or VB plain statements for this rather than Linq.

Slaggg
A: 
IEnumerable<Assembly> assemblies = ...
Assembly assemblyA = ...

// Since you say the only fact you wish to use about the class is that it
// is named 'Customer' and it exists in Assembly A, this is just about the 
// only way to construct the Type object. Pretty awful though...
Type customerType = assemblyA.GetTypes() 
                             .Single(t => t.Name == "Customer");    

// From all the types in the chosen assemblies, find the ones that subclass 
// Customer, picking the one with the deepest inheritance heirarchy.
Type bottomCustomerType = assemblies.SelectMany(a => a.GetTypes())
                                    .Where(t => t.IsSubclassOf(customerType))
                                    .OrderByDescending(t => t.GetInheritanceDepth())
                                    .First();
 ...

public static int GetInheritanceDepth(this Type type)
{
    if (type == null)
        throw new ArgumentNullException("type");

    int depth = 0;

    // Keep walking up the inheritance tree until there are no more base classes.
    while (type != null)
    {
        type = type.BaseType;
        depth++;
    }

    return depth;
}
Ani
Nice, that works. The reason to why I asked this question was to see if someone could construct a nice LINQ-query to do this, my current solution looks alot like yours.
Marcus