In my ASP.NET MVC app I'm using a small helper to iterate through all the controllers. This helper is located at a different assembly than my MVC app and I'm referencing to it.
The problem is, that when calling the Assembly.GetCallingAssembly() method in the helper, it doesn't returns the MVC app assembly, but it returns the helper assembly instead. This is not what I'm expecting to get, because all my controllers are living in the MVC app assembly and I need to reflect it.
The view code(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>
The Helper code(independent assembly):
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();
}
}
What am I doing wrong here?
I believe
GetCallingAssembly
is working - the method that callsGetSubClasses
is within your MvcHelper module (and assembly) rather than the MVC app itself. If you invokeAssembly.GetCallingAssembly
directly withinGetControllerNames
you may find you get a different result.Also note that the behaviour of
GetCallingAssembly
can vary depending on whether methods are inlined or not - see http://msdn.microsoft.com/en-us/library/system.reflection.assembly.getcallingassembly.aspxNothing. You are probably missing the fact that Razor views are compiled as separate assemblies by the ASP.NET runtime. Those assemblies are dynamic. They have nothing to do with your ASP.NET MVC application assembly. And since you are calling the helper in your view the
Assembly.GetCallingAssembly()
method will return something like this:If you want to get all controllers why not just loop through all referenced assemblies and look for types deriving from Controller? You could use the
AppDomain.CurrentDomain.GetAssemblies()
method for this. Then for each assembly justGetTypes()
and filter upon:From the
GetCallingAssembly
MSDN docs:In your case,
GetSubClasses
is called byGetControllerNames
in the same object so it should be returning the helper assembly.Edit:
From the Remarks on the MSDN docs:
So assuming the
GetSubClasses
isn't inlined, it should be returning the Assembly whichGetControllerNames
belongs to.