gpt4 book ai didi

c# - 我可以使用什么模式来避免从管道实例化不必要的 block ?

转载 作者:太空狗 更新时间:2023-10-29 23:35:52 26 4
gpt4 key购买 nike

我的 ASP.NET Core 应用程序正在使用我们自行设计的管道来处理请求。每个管道包含 1+ 个 block , block 的数量没有任何限制。在实际实例中最多可以有 200 多个 block ,管道将按配置中的顺序遍历所有 block ,例如:

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

像上面的例子(只是一个例子),在这个管道中配置了 200 多个 block ,这些 block 可以是 DoActionAddUserBlock, DoActionAddUserToRoleBlock, DoActionAddAddressToUserBlock,等等。许多 Action 混合在一个管道中。 (请不要问为什么要混用,这只是一个例子,与我的问题无关。)

对于这个例子,在每个 block 中,我们将首先检查 Action 名称,如果匹配,然后运行逻辑。但这非常糟糕,它必须实例化所有 block 并遍历所有 block 才能完成请求。

这是示例代码,不是很好,但它显示了我的痛苦:

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
{

}

我想避免按条件实例化 block ,我认为它应该在管道配置级别。我怎样才能做到这一点?属性?或其他东西。

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

//...
}

最佳答案

请告诉我们Pipeline<T>()方法(是方法还是类?),因为它对于准确回答至关重要。

无论如何,我想尽我最大的努力。

您的目标是“我想有条件地实例化 block ”,因此您必须在实异常(exception)上下文中移动您的条件,这可以通过属性来实现:

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

然后,检查 .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();
}

希望这对您有所帮助!

关于c# - 我可以使用什么模式来避免从管道实例化不必要的 block ?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58088630/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com