简体   繁体   中英

Creating extensions for Pipeline from Parallel Extensions Extras

I truly enjoy working with Parallel Extensions Extras , but must admit, still find myself challenged when it comes to creating extensions for Fluent programming methods.

I have a particular need, given this simple BusinessEntity following the Null Object Pattern

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

    private class NullBusinessEntity : BusinessEntity
    {
    }
}

How would I go about creating a "conditional Next" step, which would execute the body of the function only if a condition was met?

For now this is what I do:

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

Then in the pipeline I invoke it like so:

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

Is there a way to create an Extension to the Pipeline, specific to my BusinessEntity (or not), which would allow me to call it like this:

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

Is that possible?

If you wanted to make a generic extension for this that's conditional on null , you just need to write an extension method that invokes Next() with your conditional lambda like:

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));
}

The problem with the null object pattern is that it's not usable in generic methods, so you will have to make it specific to your type:

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));
}

In both cases, the usage would look like this:

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM