Tyler Buchanan
Tyler Buchanan

Reputation: 311

How to get reference types base class type

So I am trying to figure out how to get referenced assemblies base class type. For example I have the following:

Solution A{

..Project A

....class w

......GetAllClassesSubclassOfClassX() { return constructor if matched }

--Project B

----abstract class x

------abstract methodA()

..Project C

....class y : x

......override methodA()

--Project D

----class z : x

------override methodA()

So my current code pulls back the references but I'm not sure how to see if they are subclasses of a specific class type.

public List<AbstractCWThirdPartyConsumer> GetAllProviders()
{
    AssemblyName[] types = Assembly.GetExecutingAssembly().GetReferencedAssemblies();

    List<AbstractCWThirdPartyConsumer> listOfAllProcessors = new List<AbstractCWThirdPartyConsumer>();
    foreach (AssemblyName type in types)
    {
        if (IsSameOrSubclass(listOfAllProcessors.GetType(), type.GetType()))
        {
             //AbstractCWThirdPartyConsumer proc = (AbstractCWThirdPartyConsumer)type.GetConstructor(Type.EmptyTypes).Invoke(null);
             //listOfAllProcessors.Add(proc);
        }
    }

        return listOfAllProcessors;
    }

    public bool IsSameOrSubclass(Type potentialBase, Type potentialDescendant)
    {
        return potentialDescendant.IsSubclassOf(potentialBase);
    }
}

Any help with correcting my problem would be helpful! Thanks in advance.

Upvotes: 0

Views: 294

Answers (1)

CSharpie
CSharpie

Reputation: 9477

Why dont you use Type.IsSubclassOf.

Rewrite your method like this should do.

public bool IsSameOrSubclass(Type potentialBase, Type potentialDescendant)
{
    return potentialDescendant.IsSubclassOf(potentialBase);
}

Also i do bellieve your approach to enumerate all Types in the assemblies is incorrect so here is a rewritten Version that should fitt your intention:

using System.Linq;
...
public List<AbstractCWThirdPartyConsumer> GetAllProviders()
{
    IEnumerable<Assembly> referencedAssemblies = Assembly.GetExecutingAssembly().GetReferencedAssemblies().Select(Assembly.Load);

    List<AbstractCWThirdPartyConsumer> listOfAllProcessors = new List<AbstractCWThirdPartyConsumer>();
    foreach (Assembly assembly in referencedAssemblies)
    {
        foreach(Type type in assembly.ExportedTypes)
        {
            if (IsSameOrSubclass(typeof(AbstractCWThirdPartyConsumer), type))
            {
             //AbstractCWThirdPartyConsumer proc = (AbstractCWThirdPartyConsumer)Activator.CreateInstance(type);
             //listOfAllProcessors.Add(proc);
            } 
        }
    }
    return listOfAllProcessors;
}

public bool IsSameOrSubclass(Type potentialBase, Type potentialDescendant)
{
    return potentialDescendant.IsSubclassOf(potentialBase);
}

Or if you really want to squeeze it into a single Linq-Method-Chain:

public List<AbstractCWThirdPartyConsumer> GetAllProviders()
{
     return Assembly.GetExecutingAssembly()
             .GetReferencedAssemblies()
             .Select(Assembly.Load)
             .SelectMany(asm => asm.ExportedTypes)
             .Where(exportedType => exportedType.IsSubclassOf(typeof(AbstractCWThirdPartyConsumer)))
             .Select(exportedType => (AbstractCWThirdPartyConsumer) Activator.CreateInstance(exportedType))
             .ToList();
}

Upvotes: 1

Related Questions