mardi 24 septembre 2019

What pattern can I use to avoid instancing unnecessary blocks from pipeline?

My ASP.NET Core application is using our self-designed pipelines to process requests. Every pipeline contains 1+ blocks, and the number of blocks have no any limit. it can be up to 200+ blocks in real instance, the pipeline will go through all blocks by a sequence from a configuration, like:

Pipeline<DoActionsPipeline>().AddBlock<DoActionAddUserBlock>().AddBlock<DoActionAddUserToRoleBlock>()... 

Like above example(just an example), and there are 200+ blocks configured in this pipeline, the blocks could be DoActionAddUserBlock, DoActionAddUserToRoleBlock, DoActionAddAddressToUserBlock, and so on. many actions are mixed in one pipeline. (Please don't ask why mix them, it's just an example, it doesn't matter to my question.)

For this example, in each block, we will check the action name first, if match, then run logics. but this is pretty bad, it has to instance all blocks and go throgh all of them to get a request done.

Here is sample code, not very good, but it shows my pain:

public class DoActionAddUserBlock : BaseBlock<User, User, Context>
{
    public override User Execute(User arg, Context context)
    {
        if (context.ActionName != "AddUser")
        {
            return arg;
        }

        return AddUser(arg);
    }

    protected User AddUser(User user)
    {
        return user;
    }
}

public abstract class BaseBlock<TArg, TResult, TContext>
{
    public abstract TResult Execute(TArg arg, TContext context);
}

public class Context
{
    public string ActionName { get; set; }
}
public class User
{

}

I want to avoid instancing blocks by conditions, I think it should be in pipeline-configuration level. how can I reach this? Attributes? or something others.

[Condition("Action==AddUser")] // or [Action("AddUser")] // or [TypeOfArg("User")]
public class DoActionAddUserBlock : BaseBlock<User, User, Context>
{
    public override User Execute(User arg, Context context)
    {
        return AddUser(arg);
    }

    //...
}

Aucun commentaire:

Enregistrer un commentaire