创建示例项目
This commit is contained in:
commit
bd0c9bbf4a
|
@ -0,0 +1,35 @@
|
||||||
|
# 编译目录
|
||||||
|
bin/
|
||||||
|
obj/
|
||||||
|
.idea/
|
||||||
|
.vscode/
|
||||||
|
.vs/
|
||||||
|
|
||||||
|
# Nuget包目录
|
||||||
|
packages/
|
||||||
|
|
||||||
|
|
||||||
|
# 编译结果
|
||||||
|
[Dd]ebug/
|
||||||
|
[Rr]elease/
|
||||||
|
x64/
|
||||||
|
*_i.c
|
||||||
|
*_p.c
|
||||||
|
*.ilk
|
||||||
|
*.meta
|
||||||
|
*.obj
|
||||||
|
*.pch
|
||||||
|
*.pdb
|
||||||
|
*.pgc
|
||||||
|
*.pgd
|
||||||
|
*.rsp
|
||||||
|
*.sbr
|
||||||
|
*.tlb
|
||||||
|
*.tli
|
||||||
|
*.tlh
|
||||||
|
*.tmp
|
||||||
|
*.log
|
||||||
|
*.vspscc
|
||||||
|
*.vssscc
|
||||||
|
.builds
|
||||||
|
.fake
|
|
@ -0,0 +1,22 @@
|
||||||
|
|
||||||
|
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||||
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Core", "Core\Core.csproj", "{E6270F58-996E-4DC2-8E18-34ECF4E222AB}"
|
||||||
|
EndProject
|
||||||
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Example", "Example\Example.csproj", "{09918FD7-8BF2-4DAF-BAB9-1C97E04E458B}"
|
||||||
|
EndProject
|
||||||
|
Global
|
||||||
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
|
Debug|Any CPU = Debug|Any CPU
|
||||||
|
Release|Any CPU = Release|Any CPU
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||||
|
{E6270F58-996E-4DC2-8E18-34ECF4E222AB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
|
{E6270F58-996E-4DC2-8E18-34ECF4E222AB}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{E6270F58-996E-4DC2-8E18-34ECF4E222AB}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{E6270F58-996E-4DC2-8E18-34ECF4E222AB}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
{09918FD7-8BF2-4DAF-BAB9-1C97E04E458B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
|
{09918FD7-8BF2-4DAF-BAB9-1C97E04E458B}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{09918FD7-8BF2-4DAF-BAB9-1C97E04E458B}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{09918FD7-8BF2-4DAF-BAB9-1C97E04E458B}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
EndGlobalSection
|
||||||
|
EndGlobal
|
|
@ -0,0 +1,14 @@
|
||||||
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<TargetFramework>net7.0</TargetFramework>
|
||||||
|
<ImplicitUsings>enable</ImplicitUsings>
|
||||||
|
<Nullable>enable</Nullable>
|
||||||
|
<RootNamespace>Demo</RootNamespace>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<Folder Include="Extensions" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
</Project>
|
|
@ -0,0 +1,38 @@
|
||||||
|
using Demo.Models;
|
||||||
|
|
||||||
|
namespace Demo.Features;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 默认的功能类,做委托容器用
|
||||||
|
/// </summary>
|
||||||
|
/// <typeparam name="TMetadata"></typeparam>
|
||||||
|
public sealed class DefaultFeature<TMetadata> : Feature<TMetadata>
|
||||||
|
where TMetadata : IMetadata
|
||||||
|
{
|
||||||
|
public DefaultFeature(string name, FeatureFunction<TMetadata>? executeFunction = null,
|
||||||
|
FeatureFunctionAsync<TMetadata>? executeFunctionAsync = null,
|
||||||
|
int order = 1)
|
||||||
|
{
|
||||||
|
_executeFunction = executeFunction;
|
||||||
|
_executeFunctionAsync = executeFunctionAsync;
|
||||||
|
Name = name;
|
||||||
|
Order = order;
|
||||||
|
}
|
||||||
|
|
||||||
|
private readonly FeatureFunction<TMetadata>? _executeFunction;
|
||||||
|
|
||||||
|
private readonly FeatureFunctionAsync<TMetadata>? _executeFunctionAsync;
|
||||||
|
|
||||||
|
public override void Execute(TMetadata metadata)
|
||||||
|
{
|
||||||
|
_executeFunction?.Invoke(this, metadata);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override async ValueTask ExecuteAsync(TMetadata metadata)
|
||||||
|
{
|
||||||
|
if (_executeFunctionAsync is not null)
|
||||||
|
{
|
||||||
|
await _executeFunctionAsync.Invoke(this, metadata);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,43 @@
|
||||||
|
using Demo.Models;
|
||||||
|
|
||||||
|
namespace Demo.Features;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 抽象功能类
|
||||||
|
/// </summary>
|
||||||
|
public abstract class Feature<TMetadata>
|
||||||
|
where TMetadata : IMetadata
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 执行顺序
|
||||||
|
/// </summary>
|
||||||
|
public int Order { get; init; }
|
||||||
|
|
||||||
|
public bool Finished { get; protected set; }
|
||||||
|
|
||||||
|
public string Name { get; init; } = String.Empty;
|
||||||
|
|
||||||
|
public abstract void Execute(TMetadata metadata);
|
||||||
|
|
||||||
|
public virtual ValueTask ExecuteAsync(TMetadata metadata)
|
||||||
|
{
|
||||||
|
Execute(metadata);
|
||||||
|
return ValueTask.CompletedTask;
|
||||||
|
}
|
||||||
|
|
||||||
|
public virtual void OnException(FeatureExceptionContext<TMetadata> context)
|
||||||
|
{
|
||||||
|
throw context.Exception;
|
||||||
|
}
|
||||||
|
|
||||||
|
public virtual ValueTask OnExceptionAsync(FeatureExceptionContext<TMetadata> context)
|
||||||
|
{
|
||||||
|
throw context.Exception;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public delegate void FeatureFunction<TMetadata>(Feature<TMetadata> feature, TMetadata metadata)
|
||||||
|
where TMetadata : IMetadata;
|
||||||
|
|
||||||
|
public delegate ValueTask FeatureFunctionAsync<TMetadata>(Feature<TMetadata> feature, TMetadata metadata)
|
||||||
|
where TMetadata : IMetadata;
|
|
@ -0,0 +1,19 @@
|
||||||
|
using Demo.Models;
|
||||||
|
|
||||||
|
namespace Demo.Features;
|
||||||
|
|
||||||
|
public class FeatureException<TMetadata> : Exception
|
||||||
|
where TMetadata : IMetadata
|
||||||
|
{
|
||||||
|
public TMetadata Metadata { get; }
|
||||||
|
public Feature<TMetadata> Feature { get; }
|
||||||
|
|
||||||
|
private Exception _innerException;
|
||||||
|
|
||||||
|
public FeatureException(TMetadata metadata, Feature<TMetadata> feature, Exception ex) : base(ex.Message)
|
||||||
|
{
|
||||||
|
Metadata = metadata;
|
||||||
|
Feature = feature;
|
||||||
|
_innerException = ex;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,23 @@
|
||||||
|
using Demo.Models;
|
||||||
|
|
||||||
|
namespace Demo.Features;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 功能运行时异常上下文
|
||||||
|
/// </summary>
|
||||||
|
public class FeatureExceptionContext<TMetadata>
|
||||||
|
where TMetadata : IMetadata
|
||||||
|
{
|
||||||
|
public Feature<TMetadata> Feature { get; }
|
||||||
|
public FeatureException<TMetadata> Exception { get; }
|
||||||
|
public FeatureExceptionContext(Feature<TMetadata> feature, FeatureException<TMetadata> exception)
|
||||||
|
{
|
||||||
|
Feature = feature;
|
||||||
|
Exception = exception;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 表示异常是否已处理
|
||||||
|
/// </summary>
|
||||||
|
public bool Handled { get; set; } = false;
|
||||||
|
}
|
|
@ -0,0 +1,17 @@
|
||||||
|
using System.Collections.ObjectModel;
|
||||||
|
using Demo.Models;
|
||||||
|
|
||||||
|
namespace Demo.Features;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 功能列表容器
|
||||||
|
/// </summary>
|
||||||
|
/// <typeparam name="TMetadata"></typeparam>
|
||||||
|
public class FeatureList<TMetadata> : Dictionary<string, Feature<TMetadata>>
|
||||||
|
where TMetadata : IMetadata
|
||||||
|
{
|
||||||
|
public FeatureList(IDictionary<string, Feature<TMetadata>>? list = null)
|
||||||
|
: base(list ?? new Dictionary<string, Feature<TMetadata>>())
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,144 @@
|
||||||
|
using System.ComponentModel.Design;
|
||||||
|
using Demo.Models;
|
||||||
|
|
||||||
|
namespace Demo.Features;
|
||||||
|
|
||||||
|
public class FeatureWrapper<TMetadata>
|
||||||
|
where TMetadata : IMetadata
|
||||||
|
{
|
||||||
|
private readonly TMetadata _metadata;
|
||||||
|
|
||||||
|
protected FeatureList<TMetadata> Features { get; }
|
||||||
|
|
||||||
|
public FeatureWrapper(TMetadata metadata, FeatureList<TMetadata>? 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<TMetadata>
|
||||||
|
{
|
||||||
|
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<TMetadata> feature, int order = 1)
|
||||||
|
{
|
||||||
|
if (String.IsNullOrWhiteSpace(name))
|
||||||
|
{
|
||||||
|
throw new CheckoutException("功能名称不能为空或空白字符");
|
||||||
|
}
|
||||||
|
if (feature is not null)
|
||||||
|
{
|
||||||
|
Features.TryAdd(name, new DefaultFeature<TMetadata>(name, feature, order: order));
|
||||||
|
}
|
||||||
|
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 添加功能
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="name"></param>
|
||||||
|
/// <param name="feature"></param>
|
||||||
|
/// <param name="order"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public FeatureWrapper<TMetadata> WithFeature(string name, FeatureFunctionAsync<TMetadata> feature, int order = 1)
|
||||||
|
{
|
||||||
|
if (String.IsNullOrWhiteSpace(name))
|
||||||
|
{
|
||||||
|
throw new CheckoutException("功能名称不能为空或空白字符");
|
||||||
|
}
|
||||||
|
if (feature is not null)
|
||||||
|
{
|
||||||
|
Features.TryAdd(name, new DefaultFeature<TMetadata>(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<TMetadata>(feature, new FeatureException<TMetadata>(_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<TMetadata>(feature, new FeatureException<TMetadata>(_metadata, feature, ex)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,67 @@
|
||||||
|
using Demo.Features;
|
||||||
|
using Demo.Primitives;
|
||||||
|
|
||||||
|
namespace Demo.Models;
|
||||||
|
|
||||||
|
public abstract class Chip : IMetadata
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 属性
|
||||||
|
/// </summary>
|
||||||
|
public MetadataPropertySet Properties { get; }
|
||||||
|
|
||||||
|
public string Name { get; set; }
|
||||||
|
|
||||||
|
public Version Version { get; set; } = new Version(0, 0, 0);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 功能
|
||||||
|
/// </summary>
|
||||||
|
public virtual FeatureWrapper<Chip> Features { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 公式
|
||||||
|
/// </summary>
|
||||||
|
public FormulaExecutor Formula { get; protected set; }
|
||||||
|
|
||||||
|
protected Chip(Chip? @base = null, bool needInherit = true)
|
||||||
|
{
|
||||||
|
if (needInherit)
|
||||||
|
{
|
||||||
|
Properties = @base?.Properties ?? new MetadataPropertySet();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Properties = new MetadataPropertySet();
|
||||||
|
}
|
||||||
|
Features = new FeatureWrapper<Chip>(this);
|
||||||
|
Formula = new FormulaExecutor(null, null);
|
||||||
|
Initialize();
|
||||||
|
}
|
||||||
|
|
||||||
|
public MetadataPropertySet.MetadataProperty? this[string name]
|
||||||
|
{
|
||||||
|
get => Properties.GetValue(name);
|
||||||
|
set => Properties.SetValue(name, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public Chip SetProperty(string name, object? value)
|
||||||
|
{
|
||||||
|
Properties.SetValue(name, value);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public TValue? GetProperty<TValue>(string name)
|
||||||
|
{
|
||||||
|
return Properties.GetValue(name).Cast<TValue>();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 初始化
|
||||||
|
/// </summary>
|
||||||
|
protected virtual void Initialize()
|
||||||
|
{
|
||||||
|
// var properties = this.GetType().GetProperties();
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,12 @@
|
||||||
|
namespace Demo.Models;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 公式模型类
|
||||||
|
/// </summary>
|
||||||
|
public class Formula
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 是否启用
|
||||||
|
/// </summary>
|
||||||
|
public bool Enabled { get; set; } = true;
|
||||||
|
}
|
|
@ -0,0 +1,6 @@
|
||||||
|
namespace Demo.Models;
|
||||||
|
|
||||||
|
public class FormulaExecutionContext
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,14 @@
|
||||||
|
using Demo.Features;
|
||||||
|
|
||||||
|
namespace Demo.Models;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 元数据
|
||||||
|
/// </summary>
|
||||||
|
public interface IMetadata
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 属性
|
||||||
|
/// </summary>
|
||||||
|
MetadataPropertySet Properties { get; }
|
||||||
|
}
|
|
@ -0,0 +1,110 @@
|
||||||
|
using System.Collections;
|
||||||
|
using System.Collections.Concurrent;
|
||||||
|
|
||||||
|
namespace Demo.Models;
|
||||||
|
|
||||||
|
public class MetadataPropertySet : IReadOnlyDictionary<string, MetadataPropertySet.MetadataProperty>
|
||||||
|
{
|
||||||
|
private readonly IDictionary<string, MetadataProperty> _properties;
|
||||||
|
|
||||||
|
public MetadataPropertySet()
|
||||||
|
{
|
||||||
|
_properties = new Dictionary<string, MetadataProperty>();
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool ContainsKey(string key)
|
||||||
|
{
|
||||||
|
return _properties.ContainsKey(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool TryGetValue(string key, out MetadataProperty value)
|
||||||
|
{
|
||||||
|
return _properties.TryGetValue(key, out value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public IEnumerable<string> Keys => _properties.Keys;
|
||||||
|
public IEnumerable<MetadataProperty> Values => _properties.Values;
|
||||||
|
|
||||||
|
public MetadataProperty? this[string name]
|
||||||
|
{
|
||||||
|
get => GetValue(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
internal void SetValue(string name, object value)
|
||||||
|
{
|
||||||
|
if (_properties.TryGetValue(name, out var property))
|
||||||
|
{
|
||||||
|
property.Value = value;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
property = new MetadataProperty(name, value);
|
||||||
|
_properties.TryAdd(name, property);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
internal MetadataProperty? GetValue(string name)
|
||||||
|
{
|
||||||
|
if (_properties.TryGetValue(name, out var property))
|
||||||
|
{
|
||||||
|
return property;
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public class MetadataProperty
|
||||||
|
{
|
||||||
|
public bool IsNull { get; private set; }
|
||||||
|
public Type? Type { get; private set; }
|
||||||
|
|
||||||
|
private object? _value;
|
||||||
|
/// <summary>
|
||||||
|
/// 属性值
|
||||||
|
/// </summary>
|
||||||
|
public object? Value
|
||||||
|
{
|
||||||
|
get => _value;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
IsNull = value is null;
|
||||||
|
Type = value?.GetType();
|
||||||
|
_value = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public string Name { get; init; }
|
||||||
|
|
||||||
|
public TValue? Cast<TValue>()
|
||||||
|
{
|
||||||
|
if (typeof(TValue) == Type)
|
||||||
|
{
|
||||||
|
return (TValue)Convert.ChangeType(Value, Type);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (TValue)Value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public MetadataProperty(string name, object? value)
|
||||||
|
{
|
||||||
|
(Name, Value) = (name, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override string ToString()
|
||||||
|
{
|
||||||
|
return Value?.ToString()!;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public IEnumerator<KeyValuePair<string, MetadataProperty>> GetEnumerator()
|
||||||
|
{
|
||||||
|
return _properties.GetEnumerator();
|
||||||
|
}
|
||||||
|
|
||||||
|
IEnumerator IEnumerable.GetEnumerator()
|
||||||
|
{
|
||||||
|
return GetEnumerator();
|
||||||
|
}
|
||||||
|
|
||||||
|
public int Count => _properties.Count;
|
||||||
|
}
|
|
@ -0,0 +1,21 @@
|
||||||
|
using Demo.Models;
|
||||||
|
|
||||||
|
namespace Demo.Primitives;
|
||||||
|
|
||||||
|
public class FormulaExecutor : IComputable<FormulaExecutionContext, decimal>
|
||||||
|
{
|
||||||
|
private IFormulaEngine _engine;
|
||||||
|
private FormulaExpressionParser _parser;
|
||||||
|
|
||||||
|
public FormulaExecutor(IFormulaEngine engine, FormulaExpressionParser parser)
|
||||||
|
{
|
||||||
|
_engine = engine;
|
||||||
|
_parser = parser;
|
||||||
|
}
|
||||||
|
|
||||||
|
public decimal Compute(FormulaExecutionContext context)
|
||||||
|
{
|
||||||
|
Console.WriteLine("计算过程");
|
||||||
|
return default;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,6 @@
|
||||||
|
namespace Demo.Primitives;
|
||||||
|
|
||||||
|
public class FormulaExpressionParser
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,16 @@
|
||||||
|
namespace Demo.Primitives;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 可计算单元
|
||||||
|
/// </summary>
|
||||||
|
public interface IComputable<TInput, TResult>
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 计算
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="input"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
TResult Compute(TInput input);
|
||||||
|
|
||||||
|
// TResult Compute(Func<TInput, TResult> computor);
|
||||||
|
}
|
|
@ -0,0 +1,9 @@
|
||||||
|
namespace Demo.Primitives;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 公式引擎
|
||||||
|
/// </summary>
|
||||||
|
public interface IFormulaEngine
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,14 @@
|
||||||
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<OutputType>Exe</OutputType>
|
||||||
|
<TargetFramework>net7.0</TargetFramework>
|
||||||
|
<ImplicitUsings>enable</ImplicitUsings>
|
||||||
|
<Nullable>enable</Nullable>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<ProjectReference Include="..\Core\Core.csproj" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
</Project>
|
|
@ -0,0 +1,41 @@
|
||||||
|
using Demo.Models;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
IcndChip icndChip = new IcndChip();
|
||||||
|
icndChip.SetProperty("Code", "1234")
|
||||||
|
.SetProperty("Name", "芯片");
|
||||||
|
icndChip.Features.Execute(); // 执行所有功能
|
||||||
|
|
||||||
|
icndChip.Features
|
||||||
|
.DropFeature("场频自适应功能")
|
||||||
|
.Execute();
|
||||||
|
|
||||||
|
icndChip.Features.Execute("场频自适应功能");
|
||||||
|
|
||||||
|
icndChip.Formula.Compute(new FormulaExecutionContext() // 计算公式(需要调整)
|
||||||
|
{
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
Console.WriteLine(icndChip.GetProperty<string>("Code"));
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Console.WriteLine(ex);
|
||||||
|
}
|
||||||
|
public class IcndChip : Chip
|
||||||
|
{
|
||||||
|
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