Передать значение из производного контроллера в атрибут метода в базовом контроллере - PullRequest
0 голосов
/ 27 июня 2019

Этот вопрос не о том, почему этот код не работает, а о том, есть ли какие-либо альтернативы для его работы . Я понимаю поведение сокрытия свойств и ключевое слово new.


В базовом контроллере я определил метод с атрибутом фильтра, который принимает строковый параметр. Я хочу, чтобы значение, переданное атрибуту, было определено в производных классах. Атрибуты требуют постоянной времени компиляции, что вынуждает меня использовать свойство const, запрещающее любую форму перегрузки / переопределения.

Вот код, который я закончил писать. К сожалению, ключевое слово new скрывает только свойство в производном классе и не влияет на базовый класс.

Наблюдаемое поведение : при срабатывании действия DerivedController.DoSomething активируется атрибут AttributeThatNeedsProperty со значением параметра property, равным valueToOverride (из класса BaseController)

Желаемое поведение : Когда срабатывает действие DerivedController.DoSomething, атрибут AttributeThatNeedsProperty активируется со значением параметра property, равным overridenValue (из класса DerivedController)

// Note: This code certainly won't compile, it's a quick reproduction of my setup meant to hide the implementation detail noise from my actual code. Still, it should include all the elements needed to understand the question. If not, please ask for clarification
public abstract class BaseController : Controller
{
    public const string PropertyToOverride = "valueToOverride";

    [AttributeThatNeedsProperty(PropertyToOverride)]
    public IActionResult DoSomething()
    {

    }
}

public class DerivedController : BaseController
{
    public new const string PropertyToOverride = "overridenValue";
}

public class AttributeThatNeedsProperty : Attribute, IAuthorizationFilter
{
    private string _property;

    public AttributeThatNeedsProperty(string property)
    {
        _property = property;
    }

    public void OnAuthorization(AuthorizationFilterContext context)
    {
        // [...]
    }
}

Я подумал о двух решениях, ни одно из которых мне не нравится:

  • Переопределить метод DoSomething в производном классе. Я не хочу идти по этому пути, потому что единственная цель BaseController состоит в том, чтобы избегать переопределения чего-либо в производных классах.
  • Делайте какие-то шаткие рефлексирующие вещи, чтобы изменить значение при компиляции, но я не хочу идти по этому пути, потому что рефлексия может легко стать довольно неясной и усложнить поддержку кода. Я немного исследовал этот вариант, и, похоже, нет никаких «нехитрых» способов сделать это, даже если это возможно.

Вопрос: Как передать константу времени компиляции из производного класса в атрибут, используемый в базовом классе, не используя ни отражения, ни переопределения метода в производном классе.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...