获得的所有类型的实现一个接口在Unity [英] Get All Types That Implement An Interface In Unity

查看:1634
本文介绍了获得的所有类型的实现一个接口在Unity的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

请跳到更新,如果你想只知道解决方法:



我有一个使用下面的代码来获取和运行大量工人的应用方法

  VAR类型= typeof运算(IJob); 
变种类型= AppDomain.CurrentDomain.GetAssemblies()
.SelectMany(X => x.GetTypes())
。凡(X => x.IsClass和放大器;&放大器;类型.IsAssignableFrom(X));

的foreach(在类型T型)
{
IJob OBJ = Activator.CreateInstance(T)为IJob;
obj.Run();
}

此代码工作完全按原样。然而,一些较新的就业机会的利用依赖注入来填充它们的构造函数所以这种方法不会是可行的前进。所以我在想,如果有一种方法与团结做到这一点?



我最初的想法是,我将继续与上半年再与决心更换的foreach逻辑, 。它看起来像下面这样

  VAR类型= typeof运算(IJob); 
变种类型= AppDomain.CurrentDomain.GetAssemblies()
.SelectMany(X => x.GetTypes())
。凡(X => x.IsClass和放大器;&放大器;类型.IsAssignableFrom(X));

的foreach(在类型T型)
{
IJob OBJ = Container.Resolve(T)为IJob;
obj.Run();
}



现在的问题是,一旦我定义我的UnityContainer返回类型列表如下图所示。





更新:



原来那么refelecting时在组件如果团结就是目前它会试图反映到统一的组件,如果其最终确定用了ToList会抛出异常,由于IServiceLocator的缺失元数据扩展。要解决此附加GetAssemblies后),where子句(限制范围,所需的空间将允许正常运行应用程序。

  VAR类型= typeof运算(IJob); 
变种类型= AppDomain.CurrentDomain.GetAssemblies()
。凡(X => x.FullName.StartsWith(YourNamespace))
.SelectMany(X => x.GetTypes ())
。凡(X => x.IsClass&放大器;&放大器; type.IsAssignableFrom(X));

的foreach(在类型T型)
{
IJob OBJ = Container.Resolve(T)为IJob;
obj.Run();
}


解决方案

而不是通过搜索的

所有组件,通过自定义属性过滤。这样,您就缩小显着的搜索。



这是如何创建一个自定义程序集级别的属性。



<一个HREF =http://stackoverflow.com/questions/1936953/custom-assembly-attributes>自定义程序集属性


Please skip to the UPDATE if you would like to just know the solution:

I have an application that uses the following code to get and run a number of worker methods

var type = typeof(IJob);
var types = AppDomain.CurrentDomain.GetAssemblies()
                .SelectMany(x => x.GetTypes())
                .Where(x => x.IsClass && type.IsAssignableFrom(x));

foreach (Type t in types)
{
    IJob obj = Activator.CreateInstance(t) as IJob;
    obj.Run();
}

This code works perfectly as is. However, some of the newer jobs utilize dependency injection to populate their constructors so this method will not be viable going forward. So I was wondering if there's a way to do this with unity?

My original thought was that I would continue with the first half and then replace the foreach logic with resolve so that it looks something like the following.

var type = typeof(IJob);
var types = AppDomain.CurrentDomain.GetAssemblies()
                .SelectMany(x => x.GetTypes())
                .Where(x => x.IsClass && type.IsAssignableFrom(x));

foreach (Type t in types)
{
    IJob obj = Container.Resolve(t) as IJob;
    obj.Run();
}

The problem is that as soon as I define my UnityContainer the returned types list that implement IJob suddenly gets bloated with all of these garbage Microsoft.Practices classes as shown below

UPDATE:

It turns out then when refelecting over Assemblies if Unity is present it will attempt to reflect into Unity's assemblies which if Finalized with a ToList will throw an exception due to a missing metadata extension of IServiceLocator. To work around this appending a where clause after GetAssemblies() to limit scope to your desired namespace will allow the application to run properly.

var type = typeof(IJob);
var types = AppDomain.CurrentDomain.GetAssemblies()
                .Where(x => x.FullName.StartsWith("YourNamespace"))
                .SelectMany(x => x.GetTypes())
                .Where(x => x.IsClass && type.IsAssignableFrom(x));

foreach (Type t in types)
{
    IJob obj = Container.Resolve(t) as IJob;
    obj.Run();
}

解决方案

Instead of searching through all assemblies, filter them by a custom attribute. This way you narrow the searching dramatically.

This is how to create a custom assembly level attribute

Custom Assembly Attributes

这篇关于获得的所有类型的实现一个接口在Unity的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆