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
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 (Plain Old C# Classes) 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.
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
public List<string> GetAllEntities()
return AppDomain.CurrentDomain.GetAssemblies().SelectMany(x => x.GetTypes())
.Where(x => typeof(IDomainEntity).IsAssignableFrom(x) && !x.IsInterface && !x.IsAbstract)
.Select(x => x.Name).ToList();
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
private IPurge PurgeCache(string entity, string nameSpace)
var instance = IocContainer.Instance
.GetCurrentRegistrations().FirstOrDefault(s => s?.ServiceType?.Namespace != null
&& String.Equals(s.ServiceType.GenericTypeArguments.Name, entity, StringComparison.CurrentCultureIgnoreCase));
return (IPurge)instance.GetInstance() ?? null;
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:
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.
MethodInfoto extract information such as parameters, name, return type, access modifiers and implementation details.
EventInfoto discover event-handler data type, the name, declaring type and custom attributes.
ConstructorInfoto get data on the parameters, access modifiers, and implementation details of a constructor.
Assemblyto load modules listed in the assembly manifest.
PropertyInfoto get declaring type, reflected type, data type, name and writable status of a property or get and set property values.
CustomAttributeDatato find information on custom attributes or review attributes without having to create instances.
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.
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.