Как мне InvokeMember в унаследованном классе, который реализован только в базе - PullRequest
0 голосов
/ 18 июня 2009

Сценарий: я меняю статус «запроса», и иногда новый статус является временным и должен немедленно изменить его на другой статус. Итак, я в методе в моем базовом классе, WorkflowCommandBase:

    public virtual Request Execute()
    {
        ChangeRequestStatus();
        QueueEmails();
        TrackRequestStatus();
        return ExecuteAutoTransitionStatus(GetTransitionStatus());
    }

Последняя строка пытается выполнить метод еще раз для нового состояния (из унаследованного класса namedType), но вызываемый мной метод не существует в namedType, он реализован здесь в базе. Это возможно сделать? Или мне нужно переопределить метод Execute в унаследованных классах, когда такая ситуация существует?

private Request ExecuteAutoTransitionStatus(string commandName)
{
    if (String.IsNullOrEmpty(commandName))
    {
        return Request;
    }

    Type calledType = Type.GetType(commandName);
    return (Request)calledType.InvokeMember(
           "Execute",
           BindingFlags.InvokeMethod
                | BindingFlags.Public | BindingFlags.Instance,
           null,
           null,
           new Object[]
               {Request, TarsUser, GrantRepository, TrackingRepository});
    }

Вот часть диаграммы классов, если это поможет.

Class Diagram .

Ответы [ 2 ]

2 голосов
/ 18 июня 2009

@ Мартин: Спасибо за вашу помощь.

Я публикую это на тот случай, если это может кому-то помочь.

    private Request ExecuteAutoTransition(Type newStatus)
    {
        // No transition needed
        if (newStatus == null)
        {
            return Request;
        }

        // Create an instance of the type
        object o = Activator.CreateInstance(
            newStatus, // type
            new Object[] // constructor parameters
                {
                    Request,
                    TarsUser,
                    GrantRepository,
                    TrackingRepository
                });

        // Execute status change
        return (Request) newStatus.InvokeMember(
                             "Execute", // method
                             BindingFlags.Public 
                                | BindingFlags.Instance 
                                | BindingFlags.InvokeMethod, // binding flags
                             Type.DefaultBinder, // binder
                             o, // type
                             null); // method parameters
    }
2 голосов
/ 18 июня 2009

Что ж, на основании ваших комментариев может быть разрыв между тем, что вы написали в своем вопросе, и тем, что вы пытаетесь сделать. Поэтому я постараюсь охватить все базы.

Если метод Execute является статическим и определен для базового класса, вам необходимо добавить BindingFlags.FlattenHierarchy к вашим флагам привязки:

 BindingFlags.InvokeMethod | BindingFlags.Public
 | BindingFlags.Static | BindingFlags.FlatternHierarchy

Это кажется наиболее вероятной проблемой, потому что вы говорите, что он не находит метод, но этот флаг эффективен, только если вы ищете статический член.

С другой стороны, если метод не статический, то у вас есть правильные флаги привязки, но вам понадобится экземпляр типа для его запуска. В зависимости от того, насколько сложным является создание вашего конкретного типа, вы можете обойтись, просто используя класс Activator , в противном случае вам может понадобиться создать фабрику какого-то рода.

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