DotNetCore

Get All C# Classes Implementing an Interface

In an application I there may be an instance where you want to get a list of all classes that implement a specific interface and do something with them.

In my instance I needed to retrieve a list of Entity Classes. In the application, all Domain Entity classes implement a common interface of IDomainEntity. Although initially it may seem a little heavy handed to enforce your POCO classes to inherit and implement an interface, there is a very good reason for this.

Commonality of data

In most applications you may require some commonality of data that you will require. For instance, every Attribute may require a Name, Description, Added Date, Modified Date or even if it is visible in certain sections of your site. Although these names my be different in your data layer i.e. they map to different field names in your database, you may want to have consistency in your application layer.

In some instances, you may just want to add an Empty Marker Interface to provides a mechanism associate metadata with a class where the language does not have explicit support for such metadata.

One of the side benefits of this, is that it also provides a means for developers to identify the purpose of an entity during development. For Instance, is you notice that a class implements the IDomainEntity interface, you can immediately identify that the class is a domain entity and from there will be able to deduce which layer it is implemented in, without having to search all references etc.

These practices are most likely defined within the coding conventions of your particular environment, but I have found that although may seem heavy handed do help in eliminating ambiguity of your POCO classes throughout your stack.

The .net framework does provide support for Custom Attributes on your classes, so you may want to consider this approach if you don’t want to be bogged down by marker interfaces. Using Custom Attributes is beyond the scope of this article.

The Entities are all sorted in a Redis Distributed Cache for faster reference. We do have Session Time outs configured on our Redis Keys, but these are configured for a couple of hours.

On occasion during the course of the day, we may wan to flush the cache and reload it. This occurs as we are deploying our application to production multiple times a day. Our Build scripts are configured to call an API end point to clear specific or all Domain Entity Caches.

The issue is that we do require flexibility to flush all entities without the need to pass in a managed list of items and just ask the application itself to determine the list of entities that require flushing. It is entirely possible that new entities may have been added during the course of development or even in the previous deployment.



Power of reflection

It’s in situation like these that the power of Reflection comes into play. C# and Reflection in the .net framework are powerful tools to have in your arsenal.

The classes in the System.Reflection namespace, together with System.Type, enable you to obtain information about loaded assemblies and the types defined within, such as classes, interfaces, and value types.

The Common Language Runtime (CLR) loader manages application domains, which constitute defined boundaries around objects that have the same application scope, including loading each assembly into the appropriate application domain and controlling the memory layout of the type hierarchy within each assembly.

Assemblies contain modules, modules contain types and types contain members. Reflection provides objects that encapsulate assemblies, modules and types.

You can use reflection to dynamically create an instance of a type, bind the type to an existing object, or get the type from an existing object. You can then invoke the type’s methods or access its fields and properties.

Reflection in C#

Having a broader understanding of the capabilities of Dynamic Programming in the .net framework is certainly advantageous to your software development career.

The System.Reflection namespace contains classes that allow you to obtain information about the application and to dynamically add types, values, and objects to the application.

You can compare Reflection in .net framework to C++RTTI (Runtime Type Information), except that it has far richer capabilities. a C# program that uses reflection, uses either the TypeOf operator or the GetType() method to get the object’s type.

In the code below, I basically wrote a method that returns a list of strings containing the names of all classes implementing the IDomainEntity interface.

 

The AppDomain Represents an application domain, which is an isolated environment where applications execute. AppDomain instances are used to load and execute assemblies (Assembly).

The list above can then be used by our method to flush the entities.  We again use the power of reflection to retrieve a list of Common Data repositories defined in the Inversion Of Control container , in our case we’re making use of Simple Injector  to return the corresponding common data repository with the flush cache interface implemented

 

Reflection in .net

The base for reflection is the System.Type class, which is an abstract class representing a type in the Common Type System (CTS). The CTS class, enables the discovery of types used in a module and namespace and also determine if a given type is a reference or value type.

You can parse the metadata tables to search:

  • Fields
  • Properties
  • Fields
  • Events

In the examples above we used reflection to extract information from the application during runtime, and then to preform actions based on that data recieved.

Use cases for reflection

  • Get all global and non-global methods defined in an application.
  • Use MethodInfo to extract information such as parameters, name, return type, access modifiers and implementation details.
  • Use EventInfo to discover event-handler data type, the name, declaring type and custom attributes.
  • Use ConstructorInfo to get data on the parameters, access modifiers, and implementation details of a constructor.
  • Use Assembly to load modules listed in the assembly manifest.
  • Use PropertyInfo to get declaring type, reflected type, data type, name and writable status of a property or get and set property values.
  • Use CustomAttributeData to find information on custom attributes or review attributes without having to create instances.

Summary

The article above illustrates just how easy it is to use reflection to get information from your application regarding which classes implement specific interfaces.

It also illustrates how you can use reflection to determine which dependencies have been configured in your Inversion of Control (IOC) container.

Gary Woodfine

Freelance Full Stack Developer at threenine.co.uk
Helps businesses by improving their technical proficiencies and eliminating waste from the software development pipelines.

A unique background as business owner, marketing, software development and business development ensures that he can offer the optimum business consultancy services across a wide spectrum of business challenges.
  • Pingback: The Morning Brew - Chris Alcock » The Morning Brew #2454()

  • WhitePaper

    In your GetAllEntities method what’s the purpose behind calling Activator.CreateInstance(x).GetType() in the Select?

    • It was just a mechanism I used to create an instance of the type in order to reflect upon it . Basically just to get its name

  • Adam

    Nice, article. A good intro for people who haven’t done much reflection before. The only thing I would criticise is the title, ‘get all c# classes implementing an interface’. I wouldn’t want a beginner to think they should add an interface to every class – for example, it would be complete overkill to put an interface on your POCOs if you have no reason to do so.

    • Thanks for the feedback . I may update the content a little more to highlight that fact

  • No, it needs to be instantiated . At least that was the outcome I experienced

    • This is most definitely incorrect. You do not need to instantiate a Type to get its Name. There must be something else going on here. There are various hurdles involving unwrapping proxies if you’re working with remote appdomains, but the current appdomain has no such blockades. The Name property should be accessible without any need to instantiate it.

      • Interesting, however in my case it didn’t seem to behave as expected . So I implemented as above without any issues , noticeable impact or exceptions.

        There may well be a more efficient or eloquent approach but I just haven’t found it yet

        • Well, you’re instantiating things that don’t need to be created, for one. I’m not trying to be a pedant, but I’m genuinely curious why you’re having problems. I just cracked open LINQPad and ran the following expression without any issues (I used GetExportedTypes instead of GetTypes as it’s more efficient – I only want public types) and added a check around open generic types, but here’s what I got, and it works just fine, returning an IEnumerable of names:

          AppDomain.CurrentDomain.GetAssemblies().SelectMany(x => x.GetExportedTypes())
          .Where(t => typeof(ICloneable).IsAssignableFrom(t) &&
          !t.IsInterface &&
          !t.IsAbstract &&
          !t.ContainsGenericParameters)
          .Select(t => t.Name)

          I’m curious if it’s something to do with the load context used? If this is some kind of plugin architecture, how are you loading the DLLs?

          https://uploads.disquscdn.com/images/521b085b945de425204ce9eefb51ac283f3102b99ea2482c2ef7900c1e0b6028.png

          • Great feedback. I will knock up a sample project tomorrow to go along with this post to illustrate it all working

π