Ограничение параметров для универсального типа в пользовательском NativeActivity

#generics #workflow-foundation-4 #workflow-activity

#общие #workflow-foundation-4 #рабочий процесс-действие

Вопрос:

Есть ли способ ограничить и / или изменить параметры, предоставляемые пользователю средством выбора универсального типа при добавлении универсального действия в рабочий процесс?

Мы внедряем поддержку динамического рабочего процесса в наше приложение, и я создаю набор пользовательских действий для считывания значений из связанных бизнес-объектов в переменные рабочего процесса. Итак, теперь у нас есть такие действия, как ReadDocumentProperty<T> и SetItemProperty<T>

Эти бизнес-объекты содержат определяемые пользователем наборы свойств, которые могут быть только одним из нескольких основных типов (integer, float, string, boolean, datetime или list), поэтому нет смысла предоставлять весь набор типов .NET на выбор клиенту. Что еще хуже, тот, который они, скорее всего, захотят, — это System .Двойной (для сумм счетов и т. Д.), И его даже нет в списке по умолчанию.

Есть ли какой-либо способ изменить это приглашение: заменить его, отфильтровать, предварительно заполнить значения по умолчанию и т. Д. И при этом иметь возможность использовать общее пользовательское действие?

Ответ №1:

Новый день, новые идеи. Я действительно забыл об этом.

Если вам нужна проверка во время разработки, вполне возможно сделать что-то вроде этого:

 public sealed class MyActivity<T> : NativeActivity<T>
    {
        protected override void CacheMetadata(NativeActivityMetadata metadata)
        {
            base.CacheMetadata(metadata);

            if (typeof(T) != typeof(int) amp;amp;
                typeof(T) != typeof(bool) amp;amp;
                typeof(T) != typeof(DateTime) amp;amp;
                typeof(T) != typeof(decimal) amp;amp;
                typeof(T) != typeof(string))
            {
                metadata.AddValidationError(
                    "Generic must be 'int', 'DateTime', 'decimal' or 'string'");
            }
        }

        protected override void Execute(NativeActivityContext context)
        {
            // Execution logic 
        }
    }
 

Это вполне приемлемо, если вы предоставляете действия клиенту для разработки собственного рабочего процесса. Но имейте в виду, что это проверка во время разработки. Если кто-то использует вашу активность через код, он будет скомпилирован идеально, но при проверке / выполнении во время выполнения будет выдано исключение проверки.


Единственный способ ограничить тип для универсального действия — использовать where ключевое слово, точно так же, как вы использовали любое другое ограничение универсального типа.

Что касается диалогового окна выбора универсальных типов, если вы сделаете что-то вроде этого:

 public sealed ReadDocumentProperty<T> : CodeActivity<T>
    where T : struct
{
    //...
}
 

Диалоговое окно будет фильтровать все типы, но struct . Возможно, таким образом, System.Double отображается в списке по умолчанию, хотя это всего лишь предположение (не проверял), и, конечно, вы не можете на него полагаться. Более того, если вы впервые выберете тип, которого нет в списке по умолчанию, во второй раз он появится в нем.

Редактировать:

Насколько я понимаю, этот парень нашел способ «уменьшить»список поиска типов«, хотя он использует отражение и далек от линейного, прямого или документированного способа сделать это. Насколько я вижу, это уменьшает список для всего редактора, а не для определенного действия (считая, что вы используете повторно размещенный редактор, иначе забудьте об этом)

Комментарии:

1. Я думал об ограничении универсального типа, но я не думаю, что есть ограничение, которое соответствует тому, что я хочу (в основном только int, bool, DateTime, decimal и string)

2. Вы правы. Это проклятое ограничение C #. В любом случае, проверьте мое редактирование и посмотрите, поможет ли оно.

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

4. Извините, вы имеете в виду редактирование сверху, а не снизу 🙂 Да, это немного помогает, но для меня этого недостаточно. Я пытался сделать работу дизайнера более удобной для конечного пользователя, который привык к нашим упрощенным терминам типа (например, мы говорим «Целое число», «Число» и «True или False» вместо int, double и bool .) Я отмечу ваш ответ как ответ, хотя, поскольку он частично ответил на мой вопрос 🙂