В первый раз, отправляя сюда после нескольких лет скрытия, заблаговременно за любую помощь.
Я пытаюсь создать делегат на экземпляре контроллера из статического класса, и я получаю сообщение об ошибке: "Невозможно связать с целевым методом, потому что его подпись или прозрачность безопасности несовместимы с сигнатурой типа делегата".
Ошибка возникает в методе GetReasonsForDeny, где я передаю объект и typeof (HomeController).
Мой код здесь:
public class HomeController : Project.Web.Controllers.Base.Controller
{
//Properties
IUserRepository UserRepository { get; set; }
//Constructor
HomeController(IUserRepository userRepository)
: Project.Web.Controllers.Base.Controller
{
UserRepository = userRepository;
}
public List<string> CanPerformAction(IEntity entity)
{
List<string> reasonsForDeny = new List<string>();
TestEntity domainEntity = entity as TestEntity;
if (domainEntity != null)
VerifyRules(domainEntity, UserRepository, out reasonsForDeny);
return reasonsForDeny;
}
}
public static class ControllerActionHelper
{
private static List<string> GetReasonsForDeny(IEntity entity, Type Controller)
{
List<string> reasonsForDeny = new List<string>();
MethodInfo accessMethod = controller.GetMethod("CanPerformAction");
if (accessMethod != null)
{
/***** Error Here ********/
Func<IEntity, List<string>> accessDelegate = (Func<IEntity, List<string>>)Delegate.CreateDelegate(typeof(Func<IEntity, List<string>>), controller, accessMethod);
reasonsForDeny = accessDelegate(entity);
}
return reasonsForDeny
}
}
Я также попытался изменить делегирование на статический, передав null в CreateDelegate, как показано ниже, но если я это сделаю, то когда CanPerformAction вызывается, мой UserRepository имеет значение null.
// Before
Func<IEntity, List<string>> accessDelegate = (Func<IEntity, List<string>>)Delegate.CreateDelegate(typeof(Func<IEntity, List<string>>), controller, accessMethod);
// After
Func<IEntity, List<string>> accessDelegate = (Func<IEntity, List<string>>)Delegate.CreateDelegate(typeof(Func<IEntity, List<string>>), null, accessMethod);
Наконец, я попытался создать нестатический класс, который создаст делегат, а затем вернет его в статический класс, как показано ниже, но нестатический класс получает ту же ошибку: "Невозможно связать с целевым методом, потому что его подпись или прозрачность безопасности несовместима с прозрачностью типа делегата ".
public static class ControllerActionHelper
{
private static List<string> GetReasonsForDeny(IEntity entity, Type Controller)
{
List<string> reasonsForDeny = new List<string>();
MethodInfo accessMethod = controller.GetMethod("CanPerformAction");
if (accessMethod != null)
{
var tempInstance = new foo();
Func<IEntity, List<string>> accessDelegate = foo.MakeMyDelegatePlease(controller, accessMethod, entity);
reasonsForDeny = accessDelegate(entity);
}
return reasonsForDeny
}
}
public class foo
{
public Func<IEntity, List<string>> MakeMyDelegatePlease(Type controller, MethodInfo accessMethod, IEntity entity)
{
/********* Error Here ************/
Func<IEntity, List<string>> accessDelegate = (Func<IEntity, List<string>>)Delegate.CreateDelegate(typeof(Func<IEntity, List<string>>), controller, accessMethod);
return accessDelegate;
}
}
Любой совет будет очень благодарен!
Вам нужно передать экземпляр контроллера в GetReasonsForDeny
, а не только его тип, поскольку CanPerformAction
- это метод на конкретном экземпляре HomeController.
private static List<string> GetReasonsForDeny(IEntity entity, object controller)
{
List<string> reasonsForDeny = new List<string>();
MethodInfo accessMethod = controller.GetType().GetMethod("CanPerformAction");
if (accessMethod != null)
{
/***** Error Here ********/
Func<IEntity, List<string>> accessDelegate = (Func<IEntity, List<string>>)Delegate.CreateDelegate(typeof(Func<IEntity, List<string>>), controller, accessMethod);
reasonsForDeny = accessDelegate(entity);
}
return reasonsForDeny
}
Однако на немного несвязанной ноте вы сделаете жизнь намного легче для себя, если бы вы использовали интерфейс, чтобы сильно набирать этот материал, чтобы вам вообще не нужно было использовать отражение
например
interface ICanPerformAction
{
List<string> CanPerformAction(IEntity entity);
}
public class HomeController : Project.Web.Controllers.Base.Controller, ICanPerformAction
{
...
}