C# – Static Method in Interface

cfactorystatic

I'm working on software to play back log files. We have different types of logs from different providers.

I've created an interface that different classes will implement to play different logs. For example, ClassA will hande "somelog.txt" from ProviderA, ClassB will handle "another.log" from ProviderB, etc.

public interface ILogServer
{
    bool IsThisYourFile(string fileName, string[] content);
    // Other stuff not relevant to the question....
}

I use a factory to create the object. For each class, the factory calls IsThisYourFile() which evaluates the file name and/or the content to determine if the file is of the type it handles.

Ideally I would make IsThisYourFile static but that's not allowed. I want to use reflection to get all classes that implement ILogServer and call this function.

var types = from type in Assembly.GetExecutingAssembly().GetTypes()
                where type.GetInterface("ILogServer") != null
                select type;

foreach (var t in types)
{
    // Call the static function
    if ((bool)t.GetMethod("IsThisYourFile").Invoke(null, new object[] { fileName, content }))
    {
        server = (ILogServer)Activator.CreateInstance(t);
        break;
    }
}

This way, I only actually create one object, instead of creating an object of every class until the right one is found, leaving the others to the GC.

My current solution is to remove IsThisYourFile from the interface and just remember to implement it in each class as a static function. But that doesn't feel right.

Just wondering how others would implement this.

Best Answer

It seems to me that you're attempting to replicate the mechanics already made available to you by "plain old" object-orientation, motivated by a rather misplaced assumption:

This way, I only actually create one object, instead of creating an object of every class until the right one is found, leaving the others to the GC.

If you're worrying about performance or the memory footprint instantiating all ILogServer implementations, then don't. Reflection is much costlier than a simple loop at a list of implementations, and the actual memory footprint of having the list is most certainly negligible, since they are just implementations of different strategies on how to read log files, which doesn't leave much room for carrying heavy state.

TL;DR: Instead of using reflection to find all implementations of your interface, you can just instantiate all possible implementations of ILogServer and keep them in a list, from which you can call IsThisYourFile until you find a match. Plain old OO, no complex tools involved.