了解foreach循环在AppDomain中寻找的内容

时间:2013-08-10 20:18:18

标签: asp.net-mvc-4 foreach

我正在挖掘几个月前我下载的MVC示例并遇到使用foreach的{​​{1}}循环。我希望有人可以解释AppDomain.CurrentDomain循环正在搜索的内容。

foreach

我明白在foreach (var assembly in AppDomain.CurrentDomain .GetAssemblies() .Where(a => a.GetName().Name.Contains("Spring"))) { var configTypes = assembly .GetTypes() .Where(t => t.BaseType != null && t.IsClass && !t.IsAbstract && t.BaseType.IsGenericType && t.BaseType.GetGenericTypeDefinition() == typeof(EntityTypeConfiguration<>) && t.BaseType.GetGenericArguments().Any(ta => _modelInterfaceType.IsAssignableFrom(ta))); foreach (var type in configTypes) { var entityType = type.BaseType.GetGenericArguments().Single(); var entityConfig = assembly.CreateInstance(type.FullName); addMethod.MakeGenericMethod(entityType) .Invoke(modelBuilder.Configurations, new object[] { entityConfig }); } } 找到的每个程序集运行循环一次,而AppDomain.CurrentDomain.GetAssemblies只是一个过滤器,但我不确定过滤器是如何工作的还是数据呢正在.Where()中搜索。

注意:我从未使用过AppDomain函数,但实际上并不了解它是如何工作的。

2 个答案:

答案 0 :(得分:2)

值得reading a bit about AppDomains 让我们假设您了解AppDomain是什么以及它与ASP.NET的相关性 有关AppDomain.GetAssemblies方法的说明,请参阅this link

查询正在搜索加载到当前AppDomain的程序集,以查找程序集名称中包含“Spring”的任何位置。

Spring:应用程序框架。

我认为样本中有一些功能取决于是否引用了Spring。再告诉你,我需要看看剩下的代码。

编辑后@Matthew Verstraete#

好的,这是需要解释的更多代码 因此,对于每个Spring组件(或至少在名称中具有“Spring”的组件......),我们使用反射来查看类型。
我们想要的是:
  - 某些事物的子类型(t.BaseType != null
  - 不是价值类型(t.IsClass
  - 具体(没有抽象,没有接口 - !t.IsAbstract),有类型参数(t.BaseType.IsGenericType
  - 现在它变得有趣:我们正在寻找EntityTypeConfiguration<>的子类   - 我们的某些成员可以从通用类型ta => _modelInterfaceType.IsAssignableFrom(ta))

中分配

代码找到合适的类型后,会继续为每个创建的实例在ModelBuilder上创建每个invoke a generic methodsee also)的实例。

你正在挖掘的是code first configuration of entity framework

答案 1 :(得分:0)

应用程序域(AppDomain)只是.NET应用程序运行的沙箱环境。每个应用程序域都与其他域隔离,在大多数情况下,但并非总是如此,单个进程=单个域。

AppDomain.CurrentDomain指的是包含当前正在执行的代码(并引用AppDomain.CurrentDomain)的应用程序域。 GetAssemblies()获取已加载到该域的所有程序集 - 即从System.Web.Mvc.dll上的mscorlib.dll到您引用的任何其他程序集的所有程序集。

因此,循环遍历加载到应用程序中的所有程序集(+应用程序自己的程序集),但过滤到名称包含"Spring"的程序集。

LINQy foreach基本上等同于:

foreach (var assembly in AppDomain.CurrentDomain.GetAssemblies())
{
   if (!assembly.GetName().Name.Contains("Spring"))
   {
      continue;
   }
   // Do something
}

这种代码可用于例如通过反射在装配中找到特定类型 - 例如插件,控制器(MVC本身使用类似的代码来查找你的Controller类)等。

在这种情况下,它正在寻找EntityTypeConfiguration<T>的具体实现(例如EntityTypeConfiguration<SomeEntity>),其中T是从Type中存储的_modelEntityInterface派生的类型}。

然后,仍然通过Reflection,相当于这个调用:

someclass.Add<SomeEntity>(
   modelBuilder.Configurations, 
   new object[] { new EntityTypeConfiguration<SomeEntity>() }
);

(不确定它是Add,但是addMethod是指在代码的前面部分中反射找到的MethodInfo,您没有包含它 - 并且从名称该变量,方法的名称似乎可能是Add)。