Let's say I have several implementations of an interface:
public interface IDemoInterface
{
void DemoMethod();
}
public class DemoClass1 : IDemoInterface
{
public void DemoMethod()
{
Console.WriteLine("DemoClass1");
}
}
public class DemoClass2 : IDemoInterface
{
public void DemoMethod()
{
Console.WriteLine("DemoClass2");
}
}
Now, I am trying to define an array of such implementations and for each implementation call the interface method. Essentially, do something like this (what follows is a NON-WORKING code -- just an illustration of what I am trying to do):
public static void Run()
{
var demoClasses = { DemoClass1, DemoClass2};
foreach (var demoClass in demoClasses)
{
var implementation = demoClass as IDemoInterface;
implementation.DemoMethod();
}
}
What is the best way to accomplish it? Is using Reflection the only way?
From your example, it looks like you're not trying to loop through instances of classes that implement your interface. You're trying to loop through the types themselves. I'm basing it on this...
...and in your question
DemoClass
andDemoClass2
are class types, not instances of types.You could start with a collection of types and then create an instance of each type, like this. (You could also use reflection to find the class types that implement your interface.)
That will work, but there's a huge limitation: Each class must have a default constructor. Or if you're going to call a constructor, they would all need to have the same one.
In other words, if one of these classes has a constructor like this:
then
Activator.CreateInstance
will blow up unless you give it the values to pass into the constructor. But if you have an array of types and they have different constructors then it's pretty much impossible to do that. And you don't want to paint yourself into a corner where you have to write classes that can only have empty constructors.When you have an interface and classes that implement that interfaces, and you want to get instances of those classes, a dependency injection container (Ioc container) can be helpful. If you haven't used it there's a tiny bit of a learning curve, but it's a very useful tool to have in your box. Here's an example (this is from my blog) of configuring a Windsor container to "register", or declare several implementations of an interface.
(If you're not familiar with this it's going to seem totally out of nowhere, which is why I also linked to Windsor's documentation.)
In this example I've told this "container" that there are three classes that implement
IOrderValidator
.Now this container can "resolve", or return, an array of implementations of
IOrderValidator
. Notice this line near the top:Here's that class:
Notice that in the constructor there is an array of
IOrderValidator
. If I were to callthe container would create an instance of
OrderValidator
. It would detect that the constructor requires an array ofIOrderValidator
, so it would create instances of all of those other classes and place them in the array.If any of those classes also had constructors that required other values or classes, and I told the container how to create those, it would create those as needed in order to be able to create the implementations of
IOrderValidator
.The result is that I can have numerous implementations of a class, each with different constructor dependencies of their own, and I can create a collection of those implementations.
This answer doesn't go far toward really telling you how to do this, but hopefully it shows where to find the tools to accomplish this sort of thing. DI containers are very useful tools when used correctly. It's common practice in large applications and even small ones because it makes it easier to manage lots and lots of class types that may be nested inside one another while keeping it sane and understandable. It also helps us to write classes that are smaller and easier to unit test.
In addition to Windsor some other containers are Autofac, Unity, SimpleInjector, and the DI container that's included with ASP.NET Core applications.