这是我的测试代码:扩展方法GetInstructions来自此处:https : //gist.github.com/jbevain/104001
using System;
using System.Linq;
using System.Reflection;
using System.Threading.Tasks;
namespace ConsoleApp1
{
class Program
{
static void Main(string[] args)
{
typeof(TestClass)
.GetMethods()
.Where(method => method.Name == "Say" || method.Name == "Hello")
.ToList()
.ForEach(method =>
{
var calls = method.GetInstructions()
.Select(x => x.Operand as MethodInfo)
.Where(x => x != null)
.ToList();
Console.WriteLine(method);
calls.ForEach(call =>
{
Console.WriteLine($"\t{call}");
call.GetGenericArguments().ToList().ForEach(arg => Console.WriteLine($"\t\t{arg.FullName}"));
});
});
Console.ReadLine();
}
}
class TestClass
{
public async Task Say()
{
await HelloWorld.Say<IFoo>();
HelloWorld.Hello<IBar>();
} …Run Code Online (Sandbox Code Playgroud) 我的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)