Executing a Method on All Implementations of an Interface

Full source code available here.

Have you ever wanted to execute a method on all implementations of an interface? Say you have an interface called IGenerator and four implementations of it – GeneratorA, GeneratorB, GeneratorC, and GeneratorD. IGenerator is very simple, it has a single Generate(string details) method.

What I don’t want to do is –

1var generatorA = new GeneratorA();
2var generatorB = new GeneratorB();
3var generatorC = new GeneratorC();
4var generatorD = new GeneratorD();
5generatorA.Generate(someDetails);
6generatorB.Generate(someDetails);
7generatorC.Generate(someDetails);
8generatorD.Generate(someDetails);

I also don’t want to do this –

1List<IGenerator> generators = new List<IGenerator>() { new GeneratorA(), new GeneratorB(), new GeneratorC(), new GeneratorD() } ;
2foreach (var generator in generators) 
3{
4    generator.Generate(someDetails)
5}

What I want to do is find all the implementations of the interface without explicitly naming them, create instances of the implementations and call the Generate(..) method. This way I can add a GeneratorE and GeneratorF and I’ll be sure their Generate(..) methods will be called.

Finding the Implementations

This code will find all the implementations of the IGenerator interface –

1var iGenerator = typeof(IGenerator);
2var generatorsTypes = AppDomain.CurrentDomain.GetAssemblies() 
3    .SelectMany(assembly => assembly.GetTypes())
4    .Where(type => iGenerator.IsAssignableFrom(type) && type.IsClass);

On line 1 I specify the type I am going to look for.

Line 2 gets all the assemblies, line 3 gets all the types in those assemblies. Line 4 limits the type to those that implement IGenerator and are a class, checking that the type is a class is important, because without it the interface itself would be included in the result.

Activating the Implementations

At this point all we have done is find the types, we have not instantiated them, so we cannot yet call the Generate(..) methods. But of course there is a way to do just that.

1List<IGenerator> generators = new List<IGenerator>();
2 
3foreach (var generator in generatorsTypes)
4{
5    generators.Add(Activator.CreateInstance(generator) as IGenerator);
6}

Now I have a list with instances of all the implementations of IGeneraotor.

Calling the methods

Easy – generators.ForEach(g => g.Generate("Hi from a generator."));

That’s it, find the implementations, activate them, call the method. The end.

Full source code available here.

comments powered by Disqus

Related