CoRProcessor 框架为在 .NET 应用中实现责任链(Chain of Responsibility, CoR)模式提供了一种方法。它允许您定义一系列处理器,以顺序处理请求,并支持添加前置、后置和最终操作,以及异常处理。
要使用 CoRProcessor 框架,只需将 CoRProcessor
添加到您的项目中。
dotnet add package CoRProcessor
处理器必须实现 IChainProcessor<T>
接口。以下是一个简单处理器的示例:
public class SampleProcessor : IChainProcessor<MyData>
{
public async Task<MyData> Handle(MyData data, CancellationToken token = default)
{
// Process the data
Console.WriteLine("Processing in SampleProcessor");
// Call the next processor in the chain
return Task.FromResult(data);
}
}
CoRProcessor 框架支持补偿机制,允许在处理过程中发生异常时执行操作。
public class SampleProcessor : IChainProcessor<MyData>
{
public async Task<MyData> Handle(MyData data, CancellationToken token = default)
{
throw new Exception(); // 1. 发生异常
return Task.FromResult(data);
}
public FuncDelegate<MyData> CompensateOnFailure { get; set; } = (context, token) =>
{
// 2. 只要执行的链路里面发生异常, 补偿机制的方法将会被依次执行
return Task.FromResult(context);
};
}
您可以指定执行某几个处理器:
var result = await CoRProcessor<NumberContext>
.New()
.AddRange([
new AdditionProcessor(),
new AdditionProcessor(),
new AdditionProcessor(),
new AdditionProcessor(),
])
.Execute(new NumberContext()
{
Number1 = 1,
Number2 = 1,
Operation = Operation.Addition
}, default, 3, 4); // 指定了 index 为 2, 3 的处理器将会执行, 其余则不会执行
Console.WriteLine(result.Data);
您可以使用 CoRProcessor<T>
类创建和执行处理器链。如下所示:
class Program
{
public class MyData : IChainContext
{
public bool Abort { get; set; } // Abort = true, 可以跳过整个链路, 停止执行
public string Data { get; set; }
}
static async Task Main(string[] args)
{
var processors = new List<IChainProcessor<MyData>>
{
new SampleProcessor(),
new AnotherProcessor() // Another processor implementing IChainProcessor<MyData>
};
var processor = CoRProcessor<MyData>.New()
.AddRange(processors)
.GlobalPreExecute(async (data, token) =>
{
Console.WriteLine("Before action");
await Task.CompletedTask;
})
.GlobalExecuted(async (data, token) =>
{
Console.WriteLine("After action");
await Task.CompletedTask;
})
.Finally(async (data, token) =>
{
Console.WriteLine("Finally action");
await Task.CompletedTask;
})
.OnException(async (data, token) =>
{
Console.WriteLine("Exception occurred");
await Task.FromResult(false); // Returning false will not throw an exception.
});
var result = await processor.Execute(new MyData(), CancellationToken.None);
}
- New(): 创建一个新的
CoRProcessor<T>
实例。 - AddRange(IEnumerable<IChainProcessor> processors): 向链中添加一系列处理器。
- Execute(T t, CancellationToken token = default): 使用提供的数据和取消令牌执行处理器链。
- Before(FuncDelegate action): 添加一个在主要处理之前执行的操作。
- After(FuncDelegate action): 添加一个在主要处理之后执行的操作。
- Finally(FuncDelegate action): 添加一个在所有处理完成后执行的操作(即使抛出异常, 依然会始终执行)。
- OnException(FuncDelegate action): 添加一个在发生异常时执行的操作。
要处理异常,您可以使用 OnException 方法。这允许您在处理过程中发生异常时指定要执行的操作。
processor.OnException(async (data, token) =>
{
Console.WriteLine("Exception occurred");
await Task.FromResult(false); // 返回 false 将不会抛出异常。
await Task.FromResult(true); // 返回 true 将抛出异常。
});
您可以将 CoRProcessor 与微软内置的依赖注入(DI)系统集成。以下是一个示例: 只要实现了 IChainProcessor, AddCoR方法会自动注册
class Program
{
static async Task Main(string[] args)
{
var serviceProvider = new ServiceCollection()
.AddCoR(typeof(Program).Assembly)
.BuildServiceProvider();
var additionProcessor = serviceProvider.GetRequiredService<AdditionProcessor>();
var result = await CoRProcessor<NumberContext>
.New()
.AddRange(new[] { additionProcessor })
.Execute(new NumberContext
{
Number1 = 1,
Number2 = 1,
Operation = Operation.Addition
}, default);
Console.WriteLine(result);
}
}
您也可以使用 Autofac 进行依赖注入。以下是如何将 Autofac 与 CoRProcessor 框架集成: 只要实现了 IChainProcessor, AddCoR方法会自动注册
class Program
{
static async Task Main(string[] args)
{
var builder = new ContainerBuilder();
var container = builder.AddCoR(typeof(UnitTests).Assembly).Build();
var additionProcessor = container.Resolve<AdditionProcessor>();
var result = await CoRProcessor<NumberContext>
.New()
.AddRange([
additionProcessor
])
.Execute(new NumberContext()
{
Number1 = 1,
Number2 = 1,
Operation = Operation.Addition
}, default);
Console.WriteLine(result);
}
}
var result = await CoRProcessor<InsertOrUpdateOrderProcessorContext>
.New()
.AddRange([
orderPreProcessor,
orderValidaProcessor,
orderCustomerProcessor,
subTotalCalculationProcessor,
discountAndChargeCalculationProcessor,
subTotalBeforeDiscountCalculationProcessor,
taxCalculationBeforeDiscountProcessor,
taxCalculationAfterDiscountedProcessor,
tipsCalculationProcessor,
saveOrderRelationProcessor
])
.Execute(new()
{
Merchant = merchant,
Order = order,
}, cancellationToken).ConfigureAwait(false);
该项目根据 MIT 许可证授权。有关详细信息,请参阅 LICENSE 文件。