Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Register all declared child classes of a class in C#

Tags:

c#

reflection

In a proof-of-concept project I'm working on, I have a generic abstract class that I expect to be extended by a number of child classes:

public abstract class Pet {
    public abstract string PetTypeName {get;}
}

public class Dog : Pet {
    public override string PetTypeName { get { return "Dog"; } }
}

I'd like to have a static collection populated with all of the subtypes of this class:

public static List<Type> AllPetTypes = new List<Type> {
    typeof(Dog),
    typeof(Cat),
    //...
};

But this just adds one more step when we want to introduce a new subtype, and it's error prone because it's just one more thing a programmer can forget to do at runtime. How can I create a collection like this automatically, including every type in my assembly that inherits the given parent class?

Edit

In response do the question of what I would use this for:

Because we have multiple clients that use the same SaaS product, but with access to different subsets of portal "channels," it can be difficult to track how the user got to a particular page, and where they should be sent once they click "Done."

So I'm brainstorming architecture possibilities for an ASP.NET portal, where each page is really an enhanced user control that accepts a specific, strongly-typed class to hold its parameters, and all of the tasks involved in tracking breadcrumbs, URL creation, and such is abstracted away into the framework. So the framework needs to be aware of all of the controls that can be handled as if they were pages. Ideally, creating a new user control in the framework and making its code-behind class extend a certain base class would be sufficient to register that control as a new page in the system.

Which brings me to my next question: will finding the types in the given assembly, using the techniques mentioned in the proposed solutions to this question, work in the context of an ASP.NET web project where types are declared in the code-behind? I'm not really sure at what point the user controls get compiled, or if they are considered part of the web project's assembly. Does anyone have additional insights? (Should I make this a new question?)

like image 753
StriplingWarrior Avatar asked Dec 06 '22 03:12

StriplingWarrior


2 Answers

var targetAssembly = Assembly.GetExecutingAssembly(); // or whichever
var subtypes = targetAssembly.GetTypes().Where(t => t.IsSubclassOf(typeof(Pet)));
like image 120
mqp Avatar answered Dec 26 '22 10:12

mqp


You could start with something like this. This will get you all the types in the same assembly as the defining type that derive from the defining type.

class Aware {
    public static readonly IEnumerable<Type> AllTypes;
    static Aware() {
        Type awareType = typeof(Aware);
        allTypes = Assembly.GetAssembly(awareType)
                           .GetTypes()
                           .Where(t => awareType.IsAssignableFrom(t));        
    }
}

Test:

class Foo : Aware { }
class Bar : Aware { }

foreach (var type in Aware.AllTypes) {
            Console.WriteLine(type);
}

Output:

Aware
Foo
Bar

I'm most curious to know what you would use this for.

like image 31
jason Avatar answered Dec 26 '22 10:12

jason