Создание расширений для Pipeline из Parallel Extensions Extras

Мне очень нравится работать с дополнительными расширениями Parallel Extensions. но должен признать, что все еще испытываю затруднения, когда дело доходит до создания расширений для методов программирования Fluent.

У меня есть особая потребность, учитывая этот простой BusinessEntity следующий шаблон нулевого объекта

public abstract class BusinessEntity
{
    public static readonly BusinessEntity Null = new NullBusinessEntity();
    public long EntityKey { get; set; }

    private class NullBusinessEntity : BusinessEntity
    {
    }
}

Как мне создать шаг «условный следующий», который будет выполнять тело функции только в том случае, если условие будет выполнено?

На данный момент это то, что я делаю:

Func<BusinessEntity, Func<BusinessEntity,BusinessEntity>, BusinessEntity> conditional = (be, func) =>
{
    if (be.Equals(BusinessEntity.Null)) return be;
    return func.Invoke(be);
};

Затем в конвейере я вызываю его так:

Pipeline<BusinessEntity, string> pipeline = Pipeline.Create<BusinessEntity, BusinessEntity>(CheckEntity)
    .Next<BusinessEntity>(be => conditional.Invoke(be, entity => ProcessEntity(be)))
    .Next<string>(FinalResult);

Есть ли способ создать расширение для конвейера, специфичное для моего BusinessEntity (или нет), которое позволило бы мне называть его следующим образом:

Pipeline<BusinessEntity, string> pipeline = Pipeline
    .Create<BusinessEntity, BusinessEntity>(CheckEntity)
    .ConditionalNext<BusinessEntity>(ProcessEntity)
    .Next<string>(FinalResult);

Это возможно?


person Darek    schedule 23.07.2014    source источник
comment
Вам не нужно писать func.Invoke(be), вы можете написать только func(be).   -  person svick    schedule 02.08.2014


Ответы (1)


Если вы хотите сделать общее расширение для этого, которое зависит от null, вам просто нужно написать метод расширения, который вызывает Next() с вашей лямбдой conditional, например:

public static Pipeline<TInput, TNextOutput>
    ConditionalNext<TInput, TOutput, TNextOutput>(
    this Pipeline<TInput, TOutput> pipeline, Func<TOutput, TNextOutput> func)
    where TOutput : class
    where TNextOutput : class
{
    return pipeline.Next(x => x == null ? null : func(x));
}

Проблема с шаблоном нулевого объекта заключается в том, что его нельзя использовать в универсальных методах, поэтому вам придется сделать его специфичным для вашего типа:

public static Pipeline<TInput, BusinessEntity> ConditionalNext<TInput>(
    this Pipeline<TInput, BusinessEntity> pipeline,
    Func<BusinessEntity, BusinessEntity> func)
{
    return pipeline.Next(x => x.Equals(BusinessEntity.Null) ? x : func(x));
}

В обоих случаях использование будет выглядеть так:

var pipeline = Pipeline.Create<BusinessEntity, BusinessEntity>(CheckEntity)
    .ConditionalNext(ProcessEntity)
    .Next(FinalResult);
person svick    schedule 02.08.2014