简体   繁体   English

使用structuremap获取和/或弹出通用接口的所有实现

[英]Getting and/or ejecting all implementations of a generic interface using structuremap

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. 在结构映射中,可以通过以下类型的调用获取IHandle的任何特定实现,因此我知道所有处理程序都存在于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. 但是,我想做的就是获取(或弹出,这就是我的最终目标)如果有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 谢谢你的帮助

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 . 可以获取所有实例,但是您只能将它们存储为System.Objectdynamic You can't cast them to what you have tried IHandle<ICommand> . 您不能将它们IHandle<ICommand>为您尝试过的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>>(); 顺便说一句,这不是ObjectFactory.GetAllInstances<IHandle<ICommand>>();的原因ObjectFactory.GetAllInstances<IHandle<ICommand>>(); returns zero items. 返回零项。 This is because there are simply no instances of plugin type IHandle<ICommand> registered. 这是因为根本没有注册插件类型IHandle<ICommand>实例。 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>>() . 您可能没有实现IHandle<ICommand>类型,但是可以完美地创建和注册它们,并使用ObjectFactory.GetAllInstances<IHandle<ICommand>>()获取它们。

So if System.Object or dynamic instances are ok you can do the following: 因此,如果可以使用System.Objectdynamic实例,则可以执行以下操作:

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. 更改objectdynamic的动态方法。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM