Skip to content

Calling a method on all classes that implement a particular interface in C#

One of the projects I’m currently working on calculates a datasource every day based on varying input data. Each datasource has its own unique calculation so my plan was to create an interface that defines a Calculate() method, have all the datasource classes implement this interface with their unique calculation, and then use one or more of the popular design patterns to instantiate each class that implements the interface to call its Calculate() method to calculate the datasource value for the day. Unfortunately time became limited and I wasn’t able to figure out how to do this with design patterns, and instead turned to reflection. So here’s my implementation for calling a method on all classes that implement a particular interface.

First, I created my interface:

public interface ICalculatedSource
{
	void Calculate();
}

Next, I created my classes and encapsulated unique calculation logic in the Calculate() interface method:

public class OrangeDatasource : ICalculatedSource
{
	public void Calculate()
	{
		...
	}
}

public class BlueDatasource : ICalculatedSource
{
	public void Calculate()
	{
		...
	}
}

Finally, I used reflection to get all the classes in the current app domain that implement the ICalculatedSource interface, instantiate each one, and add it to a list. I then iterated over this list to call each instance’s Calculate() method:

IEnumerable<ICalculatedSource> sources = AppDomain.CurrentDomain.GetAssemblies()
	.SelectMany(s => s.GetTypes())
	.Where(type => typeof(ICalculatedSource).IsAssignableFrom(type)) // class implements ICalculatedSource
	.Where(type =>
		!type.IsAbstract &amp;&amp;	// class is not abstract								
		!type.IsGenericType)	// class is not generic
	.Select(type => (ICalculatedSource)Activator.CreateInstance(type)) // instantiates the class w/ its default constructor
	.ToList();

foreach (ICalculatedSource s in sources)
	s.Calculate();

Voila!

Published inTips & Tricks

Be First to Comment

Leave a Reply

Your email address will not be published. Required fields are marked *