Поиск всех методов открытых действий ASP.NET MVC, которые принимают строку в качестве параметра - PullRequest
4 голосов
/ 07 февраля 2012

Я пытаюсь использовать Nitriq , чтобы получить список всех открытых действий в моем проекте, которые принимают строку в качестве входных данных.

Вот что я пробовал:

var stringType = Types.Where(t => t.FullName == "System.String").Single();
var arTypes = Types.Where(t => t.FullName == "System.Web.Mvc.ActionResult").Single().DerivedTypes;

var results = 
from m in Methods
let DerivesFromAR = arTypes.Contains(m.ReturnType)
where m.ParameterTypes.Contains(stringType) && DerivesFromAR
select new { m.MethodId, m.Name, m.FullName };

Я использую Nitriq, потому что это кажется идеальной задачей для него, но я открыт для других подходов (желательно не для поиска всех моих методов вручную).

Ответы [ 3 ]

4 голосов
/ 08 февраля 2012

Вы должны искать не типы, полученные из System.Web.Mvc.ActionResult, а типы, полученные из System.Web.Mvc.Controller, поскольку эти классы содержат методы, возвращающие результаты действия.

Решение с использованием System.Reflection и System.Linq, используйте изнутри сборки, которая должна быть отсканирована

var controllerType = typeof(System.Web.Mvc.Controller);
var actionResultType = typeof(System.Web.Mvc.ActionResult);
var parameterType = typeof(string);

// find all controllers by checking their class
var controllers = Assembly.GetCallingAssembly().GetTypes().Where(t => controllerType.IsAssignableFrom(t));
// find all actions by checking their return type and parameter type
var actions = controllers.SelectMany(c => c.GetMethods()).Where(m => actionResultType.IsAssignableFrom(m.ReturnType) && m.GetParameters().Any(p => parameterType.IsAssignableFrom(p.ParameterType)));   
4 голосов
/ 07 февраля 2012

У меня не будет возможности проверить наверняка до сегодняшнего дня, но я думаю

var stringType = Types.Where(t => t.FullName == "System.Object").Single();

должно быть

var stringType = Types.Where(t => t.FullName == "System.String").Single();

Похоже, что сейчас вы ищете действия, которые принимают объекты вместо действий, которые принимают строки.

2 голосов
/ 08 февраля 2012

Я написал Nitriq, и на первый взгляд я подумал, что ваш запрос должен работать, но после некоторого тестирования я выяснил, почему он не возвращает желаемые значения.

Во-первых, ваш arTypes только возвращает производноеТипы ActionResult, а не ActionResult.Таким образом, теоретически ваш запрос будет возвращать методы, только если он вернет JsonResult, который наследуется от ActionResult.Я сказал теоретически, потому что коллекция DerivedTypes для объекта Nitriq Type заполняется только в тех сборках, которые вы выбрали для анализа, а не в зависимых сборках (например, System.Web.Mvc).Мы сделали это, чтобы сократить время анализа, потому что большинство людей не заботятся о том, какие методы вызываются их зависимыми сборками, иначе они также будут анализировать зависимые сборки.Однако, ретроспективно, знание производных типов зависимых сборок, вероятно, довольно полезно, и мы, вероятно, изменим его в будущем.

Предполагая, что вы не хотите добавлять System.Web.Mvc в свой проект Nitriq,Вы должны иметь возможность использовать запрос, подобный приведенному ниже, чтобы получить то, что вы хотите.

var stringType = Types.Where(t => t.FullName == "System.String").Single();
var arTypes = Types.Where(t => t.FullName == "System.Web.Mvc.ActionResult" || t.FullName == "System.Web.Mvc.JsonResult");

var results = 
from m in Methods
let DerivesFromAR = arTypes.Contains(m.ReturnType)
where m.ParameterTypes.Contains(stringType) && DerivesFromAR
select new { m.MethodId, m.Name, m.FullName };

Если вы действительно хотите добавить System.Web.Mvc, вы можете найти его по адресу

C:\Program Files (x86)\Microsoft ASP.NET\ASP.NET MVC 3\Assemblies\System.Web.Mvc.dll

В этом случае ваш новый запрос Nitriq должен быть:

var stringType = Types.Where(t => t.FullName == "System.String").Single();
var arTypes = Types.Where(t => t.FullName == "System.Web.Mvc.ActionResult").SelectMany(t => t.DerivedTypes);
var arType = Types.Where(t => t.FullName == "System.Web.Mvc.ActionResult").Single();

var results = 
from m in Methods
let DerivesFromAR = arTypes.Contains(m.ReturnType) ||  m.ReturnType == arType
where m.ParameterTypes.Contains(stringType) && DerivesFromAR
select new { m.MethodId, m.Name, m.FullName };
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...