using System.ComponentModel.Design; using Demo.Models; namespace Demo.Features; public class FeatureWrapper where TMetadata : IMetadata { private readonly TMetadata _metadata; protected FeatureList Features { get; } public FeatureWrapper(TMetadata metadata, FeatureList? features = null) { _metadata = metadata; Features = features ?? new FeatureList(); } public FeatureWrapper DropFeature(string name) { if (String.IsNullOrWhiteSpace(name)) { throw new CheckoutException("功能名称不能为空或空白字符"); } Features.Remove(name); return this; } /// /// 添加功能 /// /// /// /// public FeatureWrapper WithFeature(TFeature feature) where TFeature : Feature { if (feature is null) { return this; } if (String.IsNullOrWhiteSpace(feature.Name)) { throw new CheckoutException("功能名称不能为空或空白字符"); } Features.TryAdd(feature.Name, feature); return this; } /// /// 添加功能 /// /// /// /// /// public FeatureWrapper WithFeature(string name, FeatureFunction feature, int order = 1) { if (String.IsNullOrWhiteSpace(name)) { throw new CheckoutException("功能名称不能为空或空白字符"); } if (feature is not null) { Features.TryAdd(name, new DefaultFeature(name, feature, order: order)); } return this; } /// /// 添加功能 /// /// /// /// /// public FeatureWrapper WithFeature(string name, FeatureFunctionAsync feature, int order = 1) { if (String.IsNullOrWhiteSpace(name)) { throw new CheckoutException("功能名称不能为空或空白字符"); } if (feature is not null) { Features.TryAdd(name, new DefaultFeature(name, executeFunctionAsync: feature, order: order)); } return this; } public void Execute() { foreach (var feature in Features.Values.OrderBy(f => f.Order)) { try { feature.Execute(_metadata); if (feature.Finished) { break; } } catch (Exception ex) { feature.OnException(new FeatureExceptionContext(feature, new FeatureException(_metadata, feature, ex))); } } } public void Execute(string name) { if (Features.TryGetValue(name, out var feature)) { feature.Execute(_metadata); } else { throw new KeyNotFoundException(name); } } public async ValueTask ExecuteAsync() { foreach (var feature in Features.Values.OrderBy(f => f.Order)) { try { await feature.ExecuteAsync(_metadata); if (feature.Finished) { break; } } catch (Exception ex) { await feature.OnExceptionAsync(new FeatureExceptionContext(feature, new FeatureException(_metadata, feature, ex))); } } } }