增加全局的功能容器
This commit is contained in:
parent
976b6fb15d
commit
50159e869f
|
@ -7,8 +7,4 @@
|
|||
<RootNamespace>Demo</RootNamespace>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Folder Include="Extensions" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
|
|
@ -0,0 +1,8 @@
|
|||
using Demo.Features;
|
||||
|
||||
namespace Demo.Extensions;
|
||||
|
||||
public static class FeatureContainerExtensions
|
||||
{
|
||||
|
||||
}
|
|
@ -8,30 +8,20 @@ namespace Demo.Features;
|
|||
/// <typeparam name="TMetadata"></typeparam>
|
||||
public sealed class DefaultFeature : Feature
|
||||
{
|
||||
public DefaultFeature(string name, FeatureFunction? executeFunction = null,
|
||||
FeatureFunctionAsync? executeFunctionAsync = null,
|
||||
public DefaultFeature(string name,
|
||||
FeatureFunction? executeFunction = null,
|
||||
int order = 1)
|
||||
{
|
||||
_executeFunction = executeFunction;
|
||||
_executeFunctionAsync = executeFunctionAsync;
|
||||
Name = name;
|
||||
Order = order;
|
||||
}
|
||||
|
||||
private readonly FeatureFunction? _executeFunction;
|
||||
|
||||
private readonly FeatureFunctionAsync? _executeFunctionAsync;
|
||||
|
||||
|
||||
public override void Execute(IMetadata metadata)
|
||||
{
|
||||
_executeFunction?.Invoke(this, metadata);
|
||||
}
|
||||
|
||||
public override async ValueTask ExecuteAsync(IMetadata metadata)
|
||||
{
|
||||
if (_executeFunctionAsync is not null)
|
||||
{
|
||||
await _executeFunctionAsync.Invoke(this, metadata);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -18,23 +18,11 @@ public abstract class Feature
|
|||
|
||||
public abstract void Execute(IMetadata metadata);
|
||||
|
||||
public virtual ValueTask ExecuteAsync(IMetadata metadata)
|
||||
{
|
||||
Execute(metadata);
|
||||
return ValueTask.CompletedTask;
|
||||
}
|
||||
|
||||
public virtual void OnException(FeatureExceptionContext context)
|
||||
{
|
||||
throw context.Exception;
|
||||
}
|
||||
|
||||
public virtual ValueTask OnExceptionAsync(FeatureExceptionContext context)
|
||||
{
|
||||
throw context.Exception;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public delegate void FeatureFunction(Feature feature, IMetadata metadata);
|
||||
|
||||
public delegate ValueTask FeatureFunctionAsync(Feature feature, IMetadata metadata);
|
|
@ -0,0 +1,51 @@
|
|||
using System.Collections.Immutable;
|
||||
using Demo.Models;
|
||||
|
||||
namespace Demo.Features;
|
||||
|
||||
public class FeatureContainer : IFeatureContainer
|
||||
{
|
||||
private readonly IDictionary<string, FeatureList> _payloads;
|
||||
|
||||
private static readonly Lazy<FeatureContainer> _lazy = new Lazy<FeatureContainer>(() => new FeatureContainer());
|
||||
|
||||
private FeatureContainer()
|
||||
{
|
||||
_payloads = new Dictionary<string, FeatureList>();
|
||||
}
|
||||
|
||||
public static FeatureContainer Instance => _lazy.Value;
|
||||
|
||||
public IFeatureContainer RegisterFeature(string signId, Feature feature)
|
||||
{
|
||||
if (_payloads.TryGetValue(signId, out var features))
|
||||
{
|
||||
features.TryAdd(feature.Name, feature);
|
||||
}
|
||||
else
|
||||
{
|
||||
_payloads.TryAdd(signId, new FeatureList() { { feature.Name, feature } });
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
public IFeatureContainer RegisterWrapper(Func<IMetadata, FeatureList, IFeatureWrapper> wrapper)
|
||||
{
|
||||
_wrapper = wrapper;
|
||||
return this;
|
||||
}
|
||||
|
||||
private Func<IMetadata, FeatureList, IFeatureWrapper>? _wrapper;
|
||||
|
||||
public IFeatureWrapper BuildWrapper(IMetadata metadata)
|
||||
{
|
||||
if (_payloads.TryGetValue(metadata.SignId, out var features))
|
||||
{
|
||||
return _wrapper?.Invoke(metadata, features) ?? new FeatureWrapper(metadata, features);
|
||||
}
|
||||
|
||||
return new FeatureWrapper(metadata, features);
|
||||
}
|
||||
}
|
|
@ -7,8 +7,7 @@ namespace Demo.Features;
|
|||
/// 功能列表容器
|
||||
/// </summary>
|
||||
/// <typeparam name="TMetadata"></typeparam>
|
||||
public class FeatureList<TMetadata> : Dictionary<string, Feature>
|
||||
where TMetadata : IMetadata
|
||||
public class FeatureList : Dictionary<string, Feature>
|
||||
{
|
||||
public FeatureList(IDictionary<string, Feature>? list = null)
|
||||
: base(list ?? new Dictionary<string, Feature>())
|
||||
|
|
|
@ -3,111 +3,34 @@ using Demo.Models;
|
|||
|
||||
namespace Demo.Features;
|
||||
|
||||
public class FeatureWrapper<TMetadata>
|
||||
where TMetadata : IMetadata
|
||||
public class FeatureWrapper : IFeatureWrapper
|
||||
{
|
||||
private readonly TMetadata _metadata;
|
||||
private readonly IMetadata _metadata;
|
||||
|
||||
protected FeatureList<TMetadata> Features { get; }
|
||||
|
||||
public FeatureWrapper(TMetadata metadata, FeatureList<TMetadata>? features = null)
|
||||
protected FeatureList Features { get; }
|
||||
|
||||
public FeatureWrapper(IMetadata metadata, FeatureList? features = null)
|
||||
{
|
||||
_metadata = metadata;
|
||||
Features = features ?? new FeatureList<TMetadata>();
|
||||
}
|
||||
|
||||
public FeatureWrapper<TMetadata> DropFeature(string name)
|
||||
{
|
||||
if (String.IsNullOrWhiteSpace(name))
|
||||
{
|
||||
throw new CheckoutException("功能名称不能为空或空白字符");
|
||||
}
|
||||
Features.Remove(name);
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 添加功能
|
||||
/// </summary>
|
||||
/// <param name="feature"></param>
|
||||
/// <typeparam name="TFeature"></typeparam>
|
||||
/// <returns></returns>
|
||||
public FeatureWrapper<TMetadata> WithFeature<TFeature>(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;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 添加功能
|
||||
/// </summary>
|
||||
/// <param name="name"></param>
|
||||
/// <param name="feature"></param>
|
||||
/// <param name="order"></param>
|
||||
/// <returns></returns>
|
||||
public FeatureWrapper<TMetadata> 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;
|
||||
Features = features ?? new FeatureList();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 添加功能
|
||||
/// </summary>
|
||||
/// <param name="name"></param>
|
||||
/// <param name="feature"></param>
|
||||
/// <param name="order"></param>
|
||||
/// <returns></returns>
|
||||
public FeatureWrapper<TMetadata> 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 ExecuteAll()
|
||||
{
|
||||
foreach (var feature in Features.Values.OrderBy(f => f.Order))
|
||||
{
|
||||
try
|
||||
{
|
||||
feature.Execute(_metadata);
|
||||
if (feature.Finished)
|
||||
{
|
||||
break;
|
||||
}
|
||||
feature.Execute(_metadata);
|
||||
if (feature.Finished)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
feature.OnException(new FeatureExceptionContext(feature, new FeatureException(_metadata, feature, ex)));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -122,23 +45,4 @@ public class FeatureWrapper<TMetadata>
|
|||
throw new KeyNotFoundException(name);
|
||||
}
|
||||
}
|
||||
|
||||
public async ValueTask ExecuteAllAsync()
|
||||
{
|
||||
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)));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,15 @@
|
|||
using Demo.Models;
|
||||
|
||||
namespace Demo.Features;
|
||||
|
||||
/// <summary>
|
||||
/// 功能容器
|
||||
/// </summary>
|
||||
public interface IFeatureContainer
|
||||
{
|
||||
IFeatureContainer RegisterFeature(string signId, Feature feature);
|
||||
|
||||
IFeatureContainer RegisterWrapper(Func<IMetadata, FeatureList, IFeatureWrapper> wrapper);
|
||||
|
||||
IFeatureWrapper BuildWrapper(IMetadata metadata);
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
namespace Demo.Features;
|
||||
|
||||
public interface IFeatureWrapper
|
||||
{
|
||||
void ExecuteAll();
|
||||
|
||||
void Execute(string name);
|
||||
}
|
|
@ -5,7 +5,7 @@ namespace Demo.Models;
|
|||
|
||||
public abstract class Chip : IMetadata
|
||||
{
|
||||
public abstract Guid SignId { get; }
|
||||
public abstract string SignId { get; }
|
||||
/// <summary>
|
||||
/// 属性
|
||||
/// </summary>
|
||||
|
@ -18,7 +18,7 @@ public abstract class Chip : IMetadata
|
|||
/// <summary>
|
||||
/// 功能
|
||||
/// </summary>
|
||||
public virtual FeatureWrapper<Chip> Features { get; }
|
||||
public IFeatureWrapper Features { get; }
|
||||
|
||||
/// <summary>
|
||||
/// 公式
|
||||
|
@ -35,7 +35,8 @@ public abstract class Chip : IMetadata
|
|||
{
|
||||
Properties = new MetadataPropertySet();
|
||||
}
|
||||
Features = new FeatureWrapper<Chip>(this);
|
||||
|
||||
Features = FeatureContainer.Instance.BuildWrapper(this);
|
||||
Formula = new FormulaExecutor(null, null);
|
||||
Initialize();
|
||||
}
|
||||
|
|
|
@ -9,7 +9,7 @@ public interface IMetadata
|
|||
{
|
||||
string Name { get; }
|
||||
|
||||
Guid SignId { get; }
|
||||
string SignId { get; }
|
||||
/// <summary>
|
||||
/// 属性
|
||||
/// </summary>
|
||||
|
|
|
@ -1,22 +1,23 @@
|
|||
using Demo.Models;
|
||||
using Demo.Features;
|
||||
using Demo.Models;
|
||||
|
||||
try
|
||||
{
|
||||
FeatureContainer.Instance
|
||||
.RegisterWrapper((m, f) => new FeatureWrapper(m, f)) // 注册功能调用包装器,可以不写,默认是FeatureWrapper
|
||||
.RegisterFeature("F9168C5E-CEB2-4faa-B6BF-329BF39FA1E4", new DefaultFeature("场频自适应功能", // 注册功能
|
||||
(feature, metadata) =>
|
||||
{
|
||||
Console.WriteLine("调用场频自适应功能");
|
||||
}));
|
||||
|
||||
IcndChip icndChip = new IcndChip();
|
||||
icndChip.SetProperty("Code", "1234")
|
||||
.SetProperty("Name", "芯片");
|
||||
icndChip.Features.ExecuteAll(); // 执行所有功能
|
||||
|
||||
icndChip.Features
|
||||
.DropFeature("场频自适应功能")
|
||||
.ExecuteAll();
|
||||
|
||||
|
||||
icndChip.Features.Execute("场频自适应功能");
|
||||
|
||||
icndChip.Formula.Compute(new FormulaExecutionContext() // 计算公式(需要调整)
|
||||
{
|
||||
|
||||
});
|
||||
icndChip.Features.Execute("测试");
|
||||
|
||||
Console.WriteLine(icndChip.GetProperty<string>("Code"));
|
||||
}
|
||||
|
@ -26,18 +27,11 @@ catch (Exception ex)
|
|||
}
|
||||
public class IcndChip : Chip
|
||||
{
|
||||
public override Guid SignId => Guid.Parse("F9168C5E-CEB2-4faa-B6BF-329BF39FA1E4");
|
||||
public override string SignId => "F9168C5E-CEB2-4faa-B6BF-329BF39FA1E4";
|
||||
|
||||
protected override void Initialize()
|
||||
{
|
||||
Name = "ICND芯片";
|
||||
Features.WithFeature("场频自适应功能", (f, m) =>
|
||||
{
|
||||
Console.WriteLine($"{m.Name}调用{f.Name}");
|
||||
}).WithFeature("其他功能", (f, m) =>
|
||||
{
|
||||
Console.WriteLine($"{m.Name}调用{f.Name},得到属性[\"Code\"]值{m.GetProperty<string>("Code")}");
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue