0

I have a List of an interface:

private IList<IPlugin> plugins;

I want to have an accessor method that allows the user to get a list of implementers of said interface:

public IList<T> GetPlugins<T>() where T : IPlugin
{
   // Create list
}

I have looked at multiple examples where the Assembly is iterated. I have already achieved that as I am using MEF and so my plugins are already populated with the exported classes that inherit IPlugin.

The problem I have had is that the methods that use the Assembly do not translate over in to my List setup. I am not as versed in linq to know what is different between what the other questions used versus what i am trying to achieve.

These are the questions that i have looked at:

Edit for clarity:

Let's say I have some classes:

public class Setting : IPlugin {}
public class AppearanceSetting : Setting {}
public class WebSettings : Setting {}

If i have a list of IPlugin and i want to use my accessor call from above.

var settings = GetPlugins<Setting>(); // Get all implementors of Setting

How can i do that from a List? The examples i have found all use the Assembly. But if i have already done that using MEF, what is the best way to manipulate IList to get the classes I need? If it is even possible.

Community
  • 1
  • 1
lucasbrendel
  • 506
  • 4
  • 18

1 Answers1

2

You can get plugin classes that way:

using System.Collections.Generic;
using System;
using System.Linq;

IEnumerable<Type> getAllTheTypes() {
    return AppDomain.CurrentDomain.GetAssemblies().SelectMany(ass => ass.GetTypes());
}
IEnumerable<Type> getPluginTypes<T>() where T : IPlugin {
    return getAllTheTypes()
        .Where(typeof(T).IsAssignableFrom);
}
IEnumerable<Type> getPluginClassesWithDefaultConstructor<T>() where T : IPlugin {
    return getPluginTypes<T>()
        .Where(cls => !cls.IsAbstract)
        .Where(cls => cls.GetConstructor(new Type[] { }) != null);
}

You can instantiate them and make list:

List<T> makePlugins<T>() where T : IPlugin {
    return getPluginClassesWithDefaultConstructor<T>()
        .Select(cls => (T)cls.GetConstructor(new Type[] { }).Invoke(new object[] { }))
        .ToList();
}

But if you just need to convert List<IPlugin> to List<Setting>, plugins.OfType<Setting>().ToList() might be what you want

Jordan Szubert
  • 176
  • 1
  • 1
  • 4