使用Assembly.GetCallingAssembly()不返回调用程序集

Yai*_*vet 5 c# reflection asp.net-mvc

在我的ASP.NET MVC应用程序中,我使用一个小助手来遍历所有控制器.这个帮助器位于与我的MVC应用程序不同的程序集中,我正在引用它.

问题是,当在helper中调用Assembly.GetCallingAssembly()方法时,它不会返回MVC app程序集,而是返回帮助程序集.这不是我期望得到的,因为我的所有控制器都存在于MVC app程序集中,我需要反映它.

视图代码(MVC app assembly):

<nav>
   <ul id="menu">
      @foreach(var item in new MvcHelper().GetControllerNames())
      {
         @Html.ActionMenuItem(
              (string)HttpContext.GetGlobalResourceObject("StringsResourse", item), "Index",
              item)
      }
   </ul>
</nav>
Run Code Online (Sandbox Code Playgroud)

帮助程序代码(独立程序集):

public class MvcHelper
{
    public  List<string> GetControllerNames()
    {
        var controllerNames = new List<string>();
        GetSubClasses<Controller>().ForEach(
            type => controllerNames.Add(type.Name));
        return controllerNames;
    }

    private static List<Type> GetSubClasses<T>()
    {
        return Assembly.GetCallingAssembly().GetTypes().Where(
            type => type.IsSubclassOf(typeof(T))).ToList();
    }
}
Run Code Online (Sandbox Code Playgroud)

我在这做错了什么?

Dar*_*rov 15

我在这做错了什么?

没有.您可能错过了Razor视图由ASP.NET运行时编译为单独的程序集的事实.那些集会是动态的.它们与ASP.NET MVC应用程序程序集无关.因为你在视图中调用帮助器,所以Assembly.GetCallingAssembly()方法将返回如下内容:

App_Web_fqxdopd5, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null
Run Code Online (Sandbox Code Playgroud)

如果您想获得所有控制器,为什么不只是遍历所有引用的程序集并查找从Controller派生的类型?您可以使用此AppDomain.CurrentDomain.GetAssemblies()方法.然后对每个组件只是GetTypes()过滤:

public class MvcHelper
{
    private static List<Type> GetSubClasses<T>()
    {
        return AppDomain
            .CurrentDomain
            .GetAssemblies()
            .SelectMany(
                a => a.GetTypes().Where(type => type.IsSubclassOf(typeof(T)))
            ).ToList();
    }

    public List<string> GetControllerNames()
    {
        var controllerNames = new List<string>();
        GetSubClasses<Controller>().ForEach(
            type => controllerNames.Add(type.Name));
        return controllerNames;
    }
}
Run Code Online (Sandbox Code Playgroud)