接口方式
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 using System.Threading.Tasks; 6 7 namespace SimulateMiddleware 8 { 9 public class MiddlewareBuilder 10 { 11 private IList<Func<IMiddleware, IMiddleware>> components = new List<Func<IMiddleware, IMiddleware>>(); 12 13 public IMiddleware Builder() 14 { 15 components.Add(next => 16 { 17 return new MiddlewareA(next); 18 }); 19 components.Add(next => 20 { 21 return new MiddlewareB(next); 22 }); 23 IMiddleware start = new BaseMiddleware(); 24 foreach (var component in components.Reverse()) 25 { 26 start = component(start); 27 } 28 return start; 29 } 30 } 31 public interface IMiddleware 32 { 33 Task Invoke(); 34 } 35 36 class BaseMiddleware : IMiddleware 37 { 38 public Task Invoke() 39 { 40 Console.WriteLine("BaseMiddleware Mark"); 41 return Task.CompletedTask; 42 } 43 } 44 45 public class MiddlewareA : IMiddleware 46 { 47 IMiddleware _next; 48 public MiddlewareA(IMiddleware next) 49 { 50 _next = next; 51 } 52 53 public async Task Invoke() 54 { 55 Console.WriteLine("MiddlewareA Begin"); 56 await _next.Invoke(); 57 Console.WriteLine("MiddlewareA End"); 58 } 59 } 60 61 public class MiddlewareB : IMiddleware 62 { 63 IMiddleware _next; 64 public MiddlewareB(IMiddleware next) 65 { 66 _next = next; 67 } 68 69 public async Task Invoke() 70 { 71 Console.WriteLine("MiddlewareB Begin"); 72 await _next.Invoke(); 73 Console.WriteLine("MiddlewareB End"); 74 } 75 } 76 }
委托方式
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 using System.Threading.Tasks; 6 7 namespace SimulateMiddleware 8 { 9 public delegate Task DelegateMiddleware(); 10 public class DelegateMiddlewareBuilder 11 { 12 private IList<Func<DelegateMiddleware, DelegateMiddleware>> components = new List<Func<DelegateMiddleware, DelegateMiddleware>>(); 13 public DelegateMiddleware DirectBuilder() 14 { 15 components.Add(next => 16 { 17 return new DelegateMiddlewareA(next).Invoke; 18 }); 19 components.Add(next => 20 { 21 return new DelegateMiddlewareB(next).Invoke; 22 }); 23 DelegateMiddleware start = new BaseDelegateMiddleware().Invoke; 24 foreach (var component in components.Reverse()) 25 { 26 start = component(start); 27 } 28 return start; 29 } 30 31 public DelegateMiddleware UseBuilder() 32 { 33 Use<DelegateMiddlewareA>(); 34 Use<DelegateMiddlewareB>(); 35 DelegateMiddleware start = () => 36 { 37 Console.WriteLine("BaseDelegateMiddleware Mark"); 38 return Task.CompletedTask; 39 }; 40 foreach (var component in components.Reverse()) 41 { 42 start = component(start); 43 } 44 return start; 45 } 46 47 public void Use<TMiddleware>() 48 { 49 var middlewareType = typeof(TMiddleware); 50 var methodInfos = middlewareType.GetMethods(System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.Public); 51 var delegateMethodInfo = methodInfos.FirstOrDefault(m => m.Name.Equals("Invoke", StringComparison.OrdinalIgnoreCase)); 52 if (delegateMethodInfo == null) 53 { 54 return; 55 } 56 var isTaskReturn = typeof(Task).Equals(delegateMethodInfo.ReturnType); 57 if (!isTaskReturn) 58 { 59 return; 60 } 61 var constructorInfo = middlewareType.GetConstructor(new Type[] { typeof(DelegateMiddleware) }); 62 components.Add(next => 63 { 64 var instance = constructorInfo.Invoke(new object[] { next }); 65 var targetDelegate = (DelegateMiddleware)delegateMethodInfo.CreateDelegate(typeof(DelegateMiddleware), instance); 66 return targetDelegate; 67 }); 68 } 69 } 70 71 public class BaseDelegateMiddleware 72 { 73 public Task Invoke() 74 { 75 Console.WriteLine("BaseDelegateMiddleware Mark"); 76 return Task.CompletedTask; 77 } 78 } 79 80 public class DelegateMiddlewareA 81 { 82 DelegateMiddleware _next; 83 public DelegateMiddlewareA(DelegateMiddleware next) 84 { 85 _next = next; 86 } 87 88 public async Task Invoke() 89 { 90 Console.WriteLine("DelegateMiddlewareA Begin"); 91 await _next.Invoke(); 92 Console.WriteLine("DelegateMiddlewareA End"); 93 } 94 } 95 96 public class DelegateMiddlewareB 97 { 98 DelegateMiddleware _next; 99 public DelegateMiddlewareB(DelegateMiddleware next) 100 { 101 _next = next; 102 } 103 104 public async Task Invoke() 105 { 106 Console.WriteLine("DelegateMiddlewareB Begin"); 107 await _next.Invoke(); 108 Console.WriteLine("DelegateMiddlewareB End"); 109 } 110 } 111 }