Question

I currently have an interface of

public interface IHandle<T> where T : ICommand
{
  void Invoke(T command);
}

In structure map I can get any specific implementation of a IHandle with the following type of calls, so I know that all of my handlers exist in StructureMap.

var commandHandler = ObjectFactory.GetInstance<IHandle<SomeCommand>>();

However what I would like to do is either get (or eject as thats my eventual goal) all instances if IHandle.

I've tried the following with no success

// compile error because it doesn't have a type
ObjectFactory.GetAllInstances<IHandle<>>();

// returns 0 items
ObjectFactory.GetAllInstances<IHandle<ICommand>>();

// has runtime error of "Cannot create arrays of open type."
ObjectFactory.GetAllInstances(typeof(IHandle<>));

Does anyone know how to get all instances of a generic interface?

Thanks for any help

Était-ce utile?

La solution

If your goal is to eject them, then you can use the following code:

ObjectFactory.Model.EjectAndRemovePluginTypes(x => 
    x.IsGenericType &&
    x.GetGenericTypeDefinition() == typeof(IHandle<>)
    );

Getting all the instances is possible but you can only store them as System.Object or dynamic. You can't cast them to what you have tried IHandle<ICommand>. This isn't allowed because if it would type safety could no longer be maintained.

BTW this is not the reason why ObjectFactory.GetAllInstances<IHandle<ICommand>>(); returns zero items. This is because there are simply no instances of plugin typeIHandle<ICommand> registered. You probably don't have types that implement IHandle<ICommand> but you perfectly can create and register them and get them with ObjectFactory.GetAllInstances<IHandle<ICommand>>().

So if System.Object or dynamic instances are ok you can do the following:

IEnumerable<IPluginTypeConfiguration> handlers =
    ObjectFactory.Model.PluginTypes
                       .Where(x => x.PluginType.IsGenericType &&
                                   x.PluginType.GetGenericTypeDefinition() == 
                                                       typeof (IHandle<>));

var allInstances = new List<object>();

foreach (IPluginTypeConfiguration pluginTypeConfiguration in handlers)
{
    var instancesForPluginType = 
              ObjectFactory.GetAllInstances(pluginTypeConfiguration.PluginType)
                           .OfType<object>();

    allInstances.AddRange(instancesForPluginType);
}

Change object to dynamic for the dynamic approach.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top