Don*_*ong 5 c# design-patterns pipeline instance
我的ASP.NET Core应用程序正在使用我们自己设计的管道来处理请求。每个管道包含1个以上的块,并且块数没有任何限制。实际实例中最多可以有200个以上的块,管道将按照配置中的顺序通过所有块,例如:
Pipeline<DoActionsPipeline>().AddBlock<DoActionAddUserBlock>().AddBlock<DoActionAddUserToRoleBlock>()...
Run Code Online (Sandbox Code Playgroud)
像上述的例子(只是一个例子),并有在该管道中配置200+块,这些块可以是DoActionAddUserBlock,DoActionAddUserToRoleBlock,DoActionAddAddressToUserBlock,等。许多动作混合在一个管道中。(请不要问为什么混合它们,这只是一个例子,对我的问题无关紧要。)
对于此示例,在每个块中,我们将首先检查动作名称,如果匹配,则运行逻辑。但这很糟糕,它必须实例化所有块并通过所有这些块来完成请求。
这是示例代码,虽然不是很好,但它显示了我的痛苦:
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
{
}
Run Code Online (Sandbox Code Playgroud)
我想避免按条件实例化块,我认为它应该处于管道配置级别。我怎样才能做到这一点?属性?或其他。
[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);
}
//...
}
Run Code Online (Sandbox Code Playgroud)
请向我们展示Pipeline<T>()方法(是方法还是类?),因为它对于准确的答案至关重要。
无论如何,我想尽力利用当前的信息。
您的目标是“我想有条件地实例化块”,因此您必须在实例外上下文中移动您的条件,您可以使用属性来执行此操作:
[AttributeUsage(AttributeTargets.Class, AllowMultiple = false)]
public class ActionNameAttribute : Attribute
{
public ActionNameAttribute(string name)
{
this.Name = name;
}
public string Name { get; }
}
[ActionName(nameof(AddUser))]
public class DoActionAddUserBlock : BaseBlock<User, User, Context>
{
public override User Execute(User arg, Context context)
{
return AddUser(arg);
}
}
Run Code Online (Sandbox Code Playgroud)
然后,检查该.AddBlock<T>()方法(我猜,是类似的东西):
public YourUnknownType<T> AddBlock<TBlock>()
{
var type = typeof(TBlock);
var attributes = attributes.GetCustomAttributes(typeof(ActionNameAttribute), inherit: true); // or false if you don't need inheritation
var attribute = attributes.FirstOrDefault() as ActionNameAttribute;
if (attribute.Name == this.Context.ActioName)
{
// place here the block init
}
return AnythingYouActuallyReturn();
}
Run Code Online (Sandbox Code Playgroud)
希望这可以帮助!
| 归档时间: |
|
| 查看次数: |
211 次 |
| 最近记录: |