Browse Source

上传遗留文件

luo 8 months ago
parent
commit
b05326fc33

+ 36 - 0
EventBroker/EventArgs{T}.cs

@@ -0,0 +1,36 @@
+namespace EventBus
+{
+    public sealed class EventArgs<T> : IEventArgs<T>
+    {
+        private readonly T data;
+        private readonly Type type = typeof(void);
+        private readonly IEventBroker eventBroker;
+        private readonly IBaseEventData baseEventData;
+        private readonly Guid intPtr;
+        public IEventBroker EventBroker => eventBroker;
+        public Guid FunctionPtr => intPtr;
+        public IBaseEventData BaseEventData => baseEventData;
+        /// <summary>
+        /// 
+        /// </summary>
+        public bool Handle { get; set; }
+        /// <summary>
+        /// 事件数据
+        /// </summary>
+        public T Data => data;
+        public Type ReturnType => type;
+
+        public EventArgs(T value, IEventBroker eventBroker, Guid FuncintPtr, IBaseEventData eventData)
+        {
+            this.eventBroker = eventBroker;
+            this.intPtr = FuncintPtr;
+            data = value;
+            baseEventData = eventData;
+        }
+        public EventArgs(T value, IEventBroker eventBroker, Guid FuncintPtr, IBaseEventData eventData, Type returntype) : this(value, eventBroker, FuncintPtr, eventData)
+        {
+            this.type = returntype;
+        }
+
+    }
+}

+ 525 - 0
EventBroker/EventBroker.cs

@@ -0,0 +1,525 @@
+using System;
+using System.Collections.Concurrent;
+using System.Collections.Generic;
+using System.Diagnostics.CodeAnalysis;
+using System.Linq;
+using System.Threading.Tasks;
+
+namespace EventBus
+{
+
+    public sealed class EventBroker : IEventBroker,IDisposable
+    {
+       private static readonly Lazy<EventBroker> _eventBroker = new Lazy<EventBroker>(() => new EventBroker());
+        private EventBroker()
+        {
+
+        }
+        string GetHash()
+        {
+            return DateTime.Now.ToLongTimeString();
+        }
+        public static EventBroker Instance => _eventBroker.Value;
+        private readonly Dictionary<Type, List<IBaseEventData>> _list = new Dictionary<Type, List<IBaseEventData>>();
+        private bool disposedValue;
+        public IEventData<TData, T> GetEvent<TData, T>() 
+        {
+            lock (_list)
+            {
+                if (_list.TryGetValue(typeof(EventData<TData, T>), out List<IBaseEventData>? baseevent))
+                {
+                    baseevent ??= new List<IBaseEventData>();
+                    if (baseevent.Count == 0) baseevent.Add(new EventData<TData, T>(GetHash()));
+                    return (IEventData<TData, T>)baseevent.First();
+                }
+                else
+                {
+                    EventData<TData, T> eventData = new EventData<TData, T>(GetHash());
+                    _list.Add(typeof(EventData<TData, T>), new List<IBaseEventData>() { eventData });
+                    return eventData;
+                }
+            }
+        }
+        public IAnonymousEventData GetEvent(string eventName)
+        {
+            lock (_list)
+            {
+                ArgumentNullException.ThrowIfNullOrEmpty(eventName);
+                if (_list.TryGetValue(typeof(IAnonymousEventData), out List<IBaseEventData>? baseevent))
+                {
+                    baseevent ??= new List<IBaseEventData>();
+                    if (!baseevent.Where(x => x is AnonymousEventData && x.EventName.Contains(eventName)).Any()) baseevent.Add(new AnonymousEventData(eventName, GetHash()));
+                    return (IAnonymousEventData)baseevent.Where(x => x is AnonymousEventData && (x as AnonymousEventData)!.EventName.Contains(eventName)).First();
+                }
+                else
+                {
+                    AnonymousEventData eventData = new AnonymousEventData(eventName, GetHash());
+                    _list.Add(typeof(IAnonymousEventData), new List<IBaseEventData>() { eventData });
+                    return eventData;
+                }
+            }
+        }
+
+        public IAnonymousEventData<T> GetEvent<T>(string eventName)
+        {
+            lock (_list)
+            {
+                ArgumentNullException.ThrowIfNullOrEmpty(eventName);
+                if (_list.TryGetValue(typeof(IAnonymousEventData), out List<IBaseEventData>? baseevent))
+                {
+                    baseevent ??= new List<IBaseEventData>();
+                    if (!baseevent.Where(x => x is AnonymousEventData<T> && x.EventName.Contains(eventName)).Any()) baseevent.Add(new AnonymousEventData<T>(eventName, GetHash()));
+                    return (IAnonymousEventData<T>)baseevent.Where(x => x is AnonymousEventData<T> && (x as AnonymousEventData<T>)!.EventName.Contains(eventName)).First();
+                }
+                else
+                {
+                    AnonymousEventData<T> eventData = new AnonymousEventData<T>(eventName, GetHash());
+                    _list.Add(typeof(IAnonymousEventData), [eventData]);
+                    return eventData;
+                }
+            }
+        }
+
+        public IEventData<TData> GetEvent<TData>()
+        {
+            lock (_list)
+            {
+                if (_list.TryGetValue(typeof(EventData<TData>), out List<IBaseEventData>? baseevent))
+                {
+                    baseevent ??= new List<IBaseEventData>();
+                    if (baseevent.Count == 0) baseevent.Add(new EventData<TData>(GetHash()));
+                    return (IEventData<TData>)baseevent.First();
+                }
+                else
+                {
+                    EventData<TData> eventData = new EventData<TData>(GetHash());
+                    _list.Add(typeof(EventData<TData>), new List<IBaseEventData>() { eventData });
+                    return eventData;
+                }
+            }
+        }
+
+
+        internal abstract class BaseValue
+        {
+            public BaseValue(Properties? properties = null)
+            {
+                this.Properties = properties ?? Properties.Default;
+                this.IntPtr = Guid.NewGuid();
+            }
+            public DateTime DateTime => DateTime.Now;
+            private Properties properties = Properties.Default;
+            public Properties Properties { get => properties ?? Properties.Default; private set => properties = value; }
+            public abstract bool HasDelegate { get; }
+            public Guid IntPtr { get; internal set; }
+
+        }
+        internal class ActionValue<TData> :BaseValue
+        {
+            public ActionValue(Action<object, EventArgs<TData>> action, Properties? properties = null):base(properties)
+            {
+                this.Action = action;
+            }
+            internal Action<object, EventArgs<TData>> Action { get; set; }
+
+            public override bool HasDelegate => Action != null;
+
+
+            public bool Invoke(object sender,TData args,IBaseEventData eventData)
+            {
+                if (Action == null) return false;
+                var eventargs = new EventArgs<TData>(args, Instance, IntPtr, eventData);
+                Action.Invoke(sender, eventargs);
+                return eventargs.Handle;
+            }
+        }
+        internal abstract class BaseFuncValue<TData,TResult>:BaseValue
+        {
+            public BaseFuncValue(Properties? properties = null):base(properties)
+            {
+
+            }
+            public abstract TResult Invoke(object sender, TData data, IBaseEventData eventData);
+            public abstract List<TResult> InvokeList(object sender, TData data, IBaseEventData eventData);
+            public abstract bool IsListFunc { get; }
+        }
+        internal class FuncValue<TData,TRestlt> : BaseFuncValue<TData,TRestlt>
+        {
+            public FuncValue(Func<object, EventArgs<TData>, TRestlt> func, Properties? properties = null):base(properties)
+            {
+                Func = func;
+            }
+            internal Func<object, EventArgs<TData>, TRestlt> Func { get; private set; }
+            public override bool IsListFunc => false;
+
+            public override bool HasDelegate => Func!=null;
+
+            public override TRestlt Invoke(object sender, TData data, IBaseEventData eventData)
+            {
+                ArgumentNullException.ThrowIfNull(Func);
+                return Func.Invoke(sender, new EventArgs<TData>(data, Instance, IntPtr, eventData, typeof(TRestlt)));
+            }
+
+            public override List<TRestlt> InvokeList(object sender, TData data, IBaseEventData eventData)
+            {
+                throw new NotImplementedException();
+            }
+        }
+        internal class ListFuncValue<TData, TRestlt> : BaseFuncValue<TData,TRestlt>
+        {
+            public ListFuncValue(Func<object, EventArgs<TData>, List<TRestlt>> func, Properties? properties = null) : base( properties)
+            {
+                Func = func;
+            }
+
+            public Func<object, EventArgs<TData>, List<TRestlt>> Func { get; private set; }
+            public override bool IsListFunc => true;
+
+            public override bool HasDelegate => Func != null;
+
+            public override TRestlt Invoke(object sender, TData data, IBaseEventData eventData)
+            {
+                throw new NotImplementedException();
+            }
+
+            public override List<TRestlt> InvokeList(object sender, TData data, IBaseEventData eventData)
+            {
+                ArgumentNullException.ThrowIfNull(Func);
+                return Func.Invoke(sender, new EventArgs<TData>(data, Instance, IntPtr, eventData, typeof(TRestlt)));
+            }
+        }
+        public sealed class EventData<TData> :  IEventData<TData> 
+        {
+            public string EventName { get; }
+            public string Hash { get; }
+            internal EventData(string eventName,string hash)
+            {
+
+                EventName = eventName;
+                Hash = hash;
+            }
+            internal EventData(string hash) : this(hash, hash)
+            {
+
+            }
+            ConcurrentDictionary<Guid, ActionValue<TData>> _list = new ConcurrentDictionary<Guid, ActionValue<TData>>();
+
+            public void Publish(object sender, TData data, Properties? properties = null)
+            {
+                try
+                {
+                    ArgumentNullException.ThrowIfNull(data);
+                    properties ??= Properties.Default;
+                    if (_list.IsEmpty) return;
+                    var templist = _list.Where(x => x.Value.Properties.FilterRule(properties) && x.Value.HasDelegate).Select(x => x.Value).ToList();
+                    if (templist.Count == 0) return;
+                    foreach (var val in templist)
+                    {
+                        if (val.Invoke(sender, data, this)) return;
+                    }
+                }
+                catch
+                {
+
+                }
+            }
+            public void UnSubscrip(Guid guid)
+            {
+                lock (_list)
+                {
+                    if (guid == Guid.Empty) return;
+                    _list.TryRemove(guid,out _);
+                }
+            }
+
+            public Guid Subscrip(Action<object, EventArgs<TData>> action, Properties? properties = null)
+            {
+                lock (_list)
+                {
+                    ArgumentNullException.ThrowIfNull(action);
+                    properties ??= Properties.Default;
+                    var temp = new ActionValue<TData>(action, properties);
+                    _list[temp.IntPtr] = temp;
+                    return temp.IntPtr;
+                }
+
+            }
+            public void Clear()
+            {
+                lock (_list)
+                {
+                    _list.Clear();
+                }
+            }
+
+            public async Task PublishAsync(object sender, TData data, Properties? properties = null)
+            {
+                try
+                {
+                    ArgumentNullException.ThrowIfNull(data);
+                    properties ??= Properties.Default;
+                    if (_list.IsEmpty) return;
+                    var temp = _list.Where(x => x.Value.Properties.FilterRule(properties) && x.Value.HasDelegate).Select(x => x.Value).ToList();
+                    if (temp.Count == 0) return;
+                    foreach (var val in temp)
+                    {
+                        if (await Task.Run(() => val.Invoke(sender, data, this))) return;
+                    }
+                }
+                catch
+                {
+
+                }
+            }
+        }
+        public sealed class EventData<TData, T> :  IEventData<TData, T>
+        {
+            public string EventName { get; }
+            public string Hash { get; }
+            private readonly ConcurrentDictionary<Guid,BaseFuncValue<TData,T>> _list = new ConcurrentDictionary<Guid,BaseFuncValue<TData, T>>();
+            internal EventData(string eventName, string hash)
+            {
+                EventName = eventName;
+                Hash = hash;
+            }
+            internal EventData(string hash) : this(hash, hash)
+            {
+            }
+            public T Publish(object sender, TData data,  Properties? properties = null)
+            {
+                ArgumentNullException.ThrowIfNull(data);
+                if (_list.IsEmpty) return Activator.CreateInstance<T>();
+                properties ??= Properties.Default;
+                var func = _list.Where(x=>x.Value is FuncValue<TData,T> && x.Value.HasDelegate).Where(x => x.Value.Properties.FilterRule(properties)).Select(x=>x.Value).ToList();
+                if (func.Count == 0) return Activator.CreateInstance<T>();
+                return func.First().Invoke(sender, data, this);
+            }
+            public List<T> PublishList(object sender, TData data, Properties? properties = null)
+            {
+                ArgumentNullException.ThrowIfNull(data);
+                if (_list.IsEmpty) return new List<T>();
+                properties ??= Properties.Default;
+                var func = _list.Where(x => x.Value is ListFuncValue<TData, T> && x.Value.HasDelegate).Where(x => x.Value.Properties.FilterRule(properties)).Select(x => x.Value).ToList();
+                if (func.Count == 0) return new List<T>();
+                return func.First().InvokeList(sender, data, this);
+            }
+            public Guid Subscrip(Func<object, EventArgs<TData>, T> func,  Properties? properties = null)
+            {
+                ArgumentNullException.ThrowIfNull(func);
+                properties ??= Properties.Default;
+                var temp = new FuncValue<TData, T>(func, properties);
+                _list[temp.IntPtr] = temp;
+                return temp.IntPtr;
+            }
+
+            public Guid SubscripList( Func<object, EventArgs<TData>, List<T>> func,   Properties? properties = null)
+            {
+                ArgumentNullException.ThrowIfNull(func);
+                properties ??= Properties.Default;
+                var temp = new ListFuncValue<TData, T>(func, properties);
+                _list[temp.IntPtr] = temp;
+                return temp.IntPtr;
+            }
+
+            public void UnSubscrip(Guid intPtr)
+            {
+                if (intPtr == Guid.Empty) return;
+                _list.TryRemove(intPtr,out var _);
+            }
+
+            public void Clear()
+            {
+                _list.Clear();
+            }
+
+            public async Task<T> PublishAsync(object sender, TData data, Properties? properties = null)
+            {
+                ArgumentNullException.ThrowIfNull(data);
+                if (_list.IsEmpty) return Activator.CreateInstance<T>();
+                properties ??= Properties.Default;
+                var func = _list.Where(x => x.Value is FuncValue<TData, T> && x.Value.HasDelegate).Where(x => x.Value.Properties.FilterRule(properties)).Select(x => x.Value).ToList();
+                if (func.Count == 0) return Activator.CreateInstance<T>();
+                return await Task.Run(()=> func.First().Invoke(sender, data, this));
+            }
+
+            public async Task<List<T>> PublishListAsync(object sender, TData data, Properties? properties = null)
+            {
+                ArgumentNullException.ThrowIfNull(data);
+                if (_list.IsEmpty) return new List<T>();
+                properties ??= Properties.Default;
+                var func = _list.Where(x => x.Value is ListFuncValue<TData, T> && x.Value.HasDelegate).Where(x => x.Value.Properties.FilterRule(properties)).Select(x => x.Value).ToList();
+                if (func.Count == 0) return new List<T>();
+                return await Task.Run(() => func.First().InvokeList(sender, data, this));
+            }
+        }
+
+
+        public sealed class AnonymousEventData :  IAnonymousEventData
+        {
+            public string EventName { get; }
+            public string Hash { get; }
+            internal AnonymousEventData(string eventName, string hash)
+            {
+
+                EventName = eventName;
+                Hash = hash;
+            }
+            internal AnonymousEventData(string hash) : this(hash, hash)
+            {
+            }
+            ConcurrentDictionary<Guid, ActionValue<object[]>> _list = new ConcurrentDictionary<Guid, ActionValue<object[]>>();
+            public void Publish(object sender, Properties? properties, params object[] data)
+            {
+                
+                properties ??= Properties.Default;
+                if (_list.IsEmpty) return;
+                var templist = _list.Where(x => x.Value.Properties.FilterRule(properties) && x.Value.HasDelegate).ToList();
+                if (templist.Count == 0) return;
+                foreach (var val in templist)
+                {
+                    var args = new EventArgs<object[]>(data, Instance, val.Value.IntPtr,this);
+                    val.Value.Action.Invoke(sender, args);
+                    if (args.Handle) return;
+                }
+            }
+
+
+            public void UnSubscrip(Guid guid)
+            {
+                if (guid == Guid.Empty) return;
+                _list.TryRemove(guid, out _);
+            }
+
+            public Guid Subscrip(Action<object, EventArgs<object[]>> action,  Properties? properties=null)
+            {
+                ArgumentNullException.ThrowIfNull(action);
+                properties ??= Properties.Default;
+                var act = new ActionValue<object[]>(action, properties);
+                _list[act.IntPtr] = act;
+                return act.IntPtr;
+            }
+            public void Clear() => _list.Clear();
+
+            public async Task PublishAsync(object sender, Properties? properties = null, params object[] data)
+            {
+                properties ??= Properties.Default;
+                if (_list.IsEmpty) return;
+                var templist = _list.Where(x => x.Value.Properties.FilterRule(properties) && x.Value.HasDelegate).Select(x => x.Value).ToList();
+                foreach (var val in templist)
+                {
+                    var args = new EventArgs<object[]>(data, Instance, val.IntPtr, this);
+                    await System.Threading.Tasks.Task.Run(() => val.Action.Invoke(sender, args));
+                    if (args.Handle) return;
+                }
+            }
+        }
+        public sealed class AnonymousEventData<T> :  IAnonymousEventData<T>
+        {
+            public string EventName { get; }
+            public string Hash { get; }
+
+            ConcurrentDictionary<Guid,BaseFuncValue<object[], T>> _list = new ConcurrentDictionary<Guid, BaseFuncValue<object[], T>>();
+            internal AnonymousEventData(string eventName, string hash)
+            {
+                EventName = eventName;
+                Hash = hash;
+            }
+            internal AnonymousEventData(string hash) : this(hash, hash)
+            {
+
+            }
+            public T Publish(object sender, Properties? properties, params object[] data)
+            {
+                if (_list.IsEmpty) return Activator.CreateInstance<T>();
+                properties ??= Properties.Default;
+                var func = _list.Where(x => x.Value is FuncValue<object[], T> && x.Value.HasDelegate).Where(x => x.Value.Properties.FilterRule(properties)).Select(x=>x.Value).ToList();
+                if (func.Count == 0) return Activator.CreateInstance<T>();
+                return func.First().Invoke(sender, data, this);
+            }
+            public List<T> PublishList(object sender, Properties? properties, params object[] data)
+            {
+                if (_list.IsEmpty) return new List<T>();
+                properties ??= Properties.Default;
+                var func = _list.Where(x => x.Value is ListFuncValue<object[], T> && x.Value.HasDelegate).Where(x => x.Value.Properties.FilterRule(properties)).Select(x => x.Value).ToList();
+                if (func.Count == 0) return new List<T>();
+                return func.First().InvokeList(sender, data, this);
+            }
+            public Guid Subscrip(Func<object, EventArgs<object[]>, T> func, Properties? properties=null)
+            {
+                ArgumentNullException.ThrowIfNull(func);
+                properties ??= Properties.Default;
+                var tempfunc = new FuncValue<object[], T>(func, properties);
+                _list[tempfunc.IntPtr] = tempfunc;
+                return tempfunc.IntPtr;
+            }
+
+            public Guid SubscripList(Func<object, EventArgs<object[]>, List<T>> func, Properties? properties=null)
+            {
+                ArgumentNullException.ThrowIfNull(func);
+                properties ??= Properties.Default;
+                var tempfunc = new ListFuncValue<object[], T>(func, properties);
+                _list[tempfunc.IntPtr] = tempfunc;
+                return tempfunc.IntPtr;
+            }
+
+            public void UnSubscrip(Guid guid)
+            {
+                if (guid == Guid.Empty) return;
+                _list.TryRemove(guid, out _);
+            }
+
+            public void Clear()
+            {
+                _list.Clear();
+            }
+
+            public async Task<T> PublishAsync(object sender, Properties? properties = null, params object[] data)
+            {
+                if (_list.IsEmpty) return Activator.CreateInstance<T>();
+                properties ??= Properties.Default;
+                var func = _list.Where(x => x.Value is FuncValue<object[], T> && x.Value.HasDelegate).Where(x => x.Value.Properties.FilterRule(properties)).Select(x=>x.Value).ToList();
+                if (func.Count == 0) return Activator.CreateInstance<T>();
+                return await Task.Run(()=> func.First().Invoke(sender, data, this));
+            }
+
+            public async Task<List<T>> PublishListAsync(object sender, Properties? properties = null, params object[] data)
+            {
+                if (_list.IsEmpty) return new List<T>();
+                properties ??= Properties.Default;
+                var func = _list.Where(x => x.Value is ListFuncValue<object[], T> && x.Value.HasDelegate).Where(x => x.Value.Properties.FilterRule(properties)).Select(x => x.Value).ToList();
+                if (func.Count == 0) return new List<T>();
+                return await Task.Run(()=> func.First().InvokeList(sender, data, this));
+            }
+        }
+
+        private void Dispose(bool disposing)
+        {
+            if (!disposedValue)
+            {
+                if (disposing)
+                {
+                    _list.Values.ToList().ForEach(x => x?.ToList().ForEach(y=>y.Clear()));
+                    _list.Clear();
+                }
+
+                // TODO: 释放未托管的资源(未托管的对象)并替代终结器
+                // TODO: 将大型字段设置为 null
+                disposedValue = true;
+            }
+        }
+
+        // // TODO: 仅当“Dispose(bool disposing)”拥有用于释放未托管资源的代码时才替代终结器
+        // ~EventBroker()
+        // {
+        //     // 不要更改此代码。请将清理代码放入“Dispose(bool disposing)”方法中
+        //     Dispose(disposing: false);
+        // }
+
+        public void Dispose()
+        {
+            // 不要更改此代码。请将清理代码放入“Dispose(bool disposing)”方法中
+            Dispose(disposing: true);
+            GC.SuppressFinalize(this);
+        }
+    }
+}

+ 25 - 0
EventBroker/EventBroker.projitems

@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <PropertyGroup>
+    <MSBuildAllProjects Condition="'$(MSBuildVersion)' == '' Or '$(MSBuildVersion)' &lt; '16.0'">$(MSBuildAllProjects);$(MSBuildThisFileFullPath)</MSBuildAllProjects>
+    <HasSharedItems>true</HasSharedItems>
+    <SharedGUID>861edd04-79e4-4e4c-a406-1f1357dd24ba</SharedGUID>
+  </PropertyGroup>
+  <PropertyGroup Label="Configuration">
+    <Import_RootNamespace>EventBroker</Import_RootNamespace>
+  </PropertyGroup>
+  <ItemGroup>
+    <Compile Include="$(MSBuildThisFileDirectory)EventArgs{T}.cs" />
+    <Compile Include="$(MSBuildThisFileDirectory)EventBroker.cs" />
+    <Compile Include="$(MSBuildThisFileDirectory)IAnonymousEventData.cs" />
+    <Compile Include="$(MSBuildThisFileDirectory)IAnonymousEventData{T}.cs" />
+    <Compile Include="$(MSBuildThisFileDirectory)IBaseEventArgs.cs" />
+    <Compile Include="$(MSBuildThisFileDirectory)IBaseEventData.cs" />
+    <Compile Include="$(MSBuildThisFileDirectory)IEventArgs{T}.cs" />
+    <Compile Include="$(MSBuildThisFileDirectory)IEventBroker.cs" />
+    <Compile Include="$(MSBuildThisFileDirectory)IEventData{TData}.cs" />
+    <Compile Include="$(MSBuildThisFileDirectory)IEventData{TData_T}.cs" />
+    <Compile Include="$(MSBuildThisFileDirectory)Properties.cs" />
+    <Compile Include="$(MSBuildThisFileDirectory)PropertiesToolkit.cs" />
+  </ItemGroup>
+</Project>

+ 13 - 0
EventBroker/EventBroker.shproj

@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <PropertyGroup Label="Globals">
+    <ProjectGuid>861edd04-79e4-4e4c-a406-1f1357dd24ba</ProjectGuid>
+    <MinimumVisualStudioVersion>14.0</MinimumVisualStudioVersion>
+  </PropertyGroup>
+  <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
+  <Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\CodeSharing\Microsoft.CodeSharing.Common.Default.props" />
+  <Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\CodeSharing\Microsoft.CodeSharing.Common.props" />
+  <PropertyGroup />
+  <Import Project="EventBroker.projitems" Label="Shared" />
+  <Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\CodeSharing\Microsoft.CodeSharing.CSharp.targets" />
+</Project>

+ 24 - 0
EventBroker/IAnonymousEventData.cs

@@ -0,0 +1,24 @@
+namespace EventBus
+{
+    /// <summary>
+    /// 不带返回值的匿名事件
+    /// </summary>
+    public interface IAnonymousEventData : IBaseEventData
+    {
+        /// <summary>
+        /// 发布同步事件
+        /// </summary>
+        void Publish(object sender, Properties? properties = null, params object[] data);
+        /// <summary>
+        /// 发布异步事件
+        /// </summary>
+        Task PublishAsync(object sender, Properties? properties = null, params object[] data);
+        /// <summary>
+        /// 订阅事件
+        /// </summary>
+        /// <param name="action">事件处理函数</param>
+        /// <param name="properties">筛选器</param>
+        Guid Subscrip(Action<object, EventArgs<object[]>> action, Properties? properties = null);
+
+    }
+}

+ 40 - 0
EventBroker/IAnonymousEventData{T}.cs

@@ -0,0 +1,40 @@
+namespace EventBus
+{
+    /// <summary>
+    /// 匿名事件
+    /// </summary>
+    /// <typeparam name="T"></typeparam>
+    public interface IAnonymousEventData<T> : IBaseEventData
+    {
+        /// <summary>
+        /// 发布同步事件
+        /// </summary>
+        T Publish(object sender, Properties? properties = null, params object[] data);
+        /// <summary>
+        /// 发布异步事件
+        /// </summary>
+        Task<T> PublishAsync(object sender, Properties? properties = null, params object[] data);
+
+        /// <summary>
+        /// 发布数组请求同步事件
+        /// </summary>
+        List<T> PublishList(object sender, Properties? properties = null, params object[] data);
+        /// <summary>
+        /// 发布数组请求异步事件
+        /// </summary>
+        Task<List<T>> PublishListAsync(object sender, Properties? properties = null, params object[] data);
+
+        /// <summary>
+        /// 订阅事件
+        /// </summary>
+        /// <param name="func">事件处理函数</param>
+        /// <param name="properties">筛选器</param>
+        Guid Subscrip(Func<object, EventArgs<object[]>, T> func, Properties? properties = null);
+        /// <summary>
+        /// 订阅事件
+        /// </summary>
+        /// <param name="func">事件处理函数</param>
+        /// <param name="properties">筛选器</param>
+        Guid SubscripList(Func<object, EventArgs<object[]>, List<T>> func, Properties? properties = null);
+    }
+}

+ 7 - 0
EventBroker/IBaseEventArgs.cs

@@ -0,0 +1,7 @@
+namespace EventBus
+{
+    public interface IBaseEventArgs
+    {
+        bool Handle { get; set; }
+    }
+}

+ 23 - 0
EventBroker/IBaseEventData.cs

@@ -0,0 +1,23 @@
+namespace EventBus
+{
+    public interface IBaseEventData
+    {
+        /// <summary>
+        /// 清除所有事件订阅
+        /// </summary>
+        void Clear();
+        /// <summary>
+        /// 取消事件订阅
+        /// </summary>
+        /// <param name="guid">事件标识<see cref="RuntimeMethodHandle.Value"/></param>
+        void UnSubscrip(Guid guid);
+        /// <summary>
+        /// 事件名称
+        /// </summary>
+        string EventName { get; }
+        /// <summary>
+        /// 事件hash
+        /// </summary>
+        string Hash { get; }
+    }
+}

+ 7 - 0
EventBroker/IEventArgs{T}.cs

@@ -0,0 +1,7 @@
+namespace EventBus
+{
+    public interface IEventArgs<T> : IBaseEventArgs
+    {
+        T Data { get; }
+    }
+}

+ 32 - 0
EventBroker/IEventBroker.cs

@@ -0,0 +1,32 @@
+namespace EventBus
+{
+    public interface IEventBroker
+    {
+        /// <summary>
+        /// 根据数据类型获取事件句柄
+        /// </summary>
+        /// <typeparam name="TData">数据类型</typeparam>
+        /// <returns>事件句柄</returns>
+        IEventData<TData> GetEvent<TData>();
+        /// <summary>
+        /// 根据TData数据类型获取带返回值的事件句柄
+        /// </summary>
+        /// <typeparam name="TData">数据类型</typeparam>
+        /// <typeparam name="T">返回数据类型</typeparam>
+        /// <returns>事件句柄</returns>
+        IEventData<TData, T> GetEvent<TData, T>();
+        /// <summary>
+        /// 根据<paramref name="eventName"/>获取事件句柄
+        /// </summary>
+        /// <param name="eventName">事件名称</param>
+        /// <returns>事件句柄</returns>
+        IAnonymousEventData GetEvent(string eventName);
+        /// <summary>
+        /// 根据<paramref name="eventName"/>获取事件句柄
+        /// </summary>
+        /// <param name="eventName">事件名称</param>
+        /// <typeparam name="T">返回数据类型</typeparam>
+        /// <returns>事件句柄</returns>
+        IAnonymousEventData<T> GetEvent<T>(string eventName);
+    }
+}

+ 40 - 0
EventBroker/IEventData{TData_T}.cs

@@ -0,0 +1,40 @@
+namespace EventBus
+{
+    /// <summary>
+    /// 事件句柄
+    /// </summary>
+    /// <typeparam name="TData">事件发布数据类型</typeparam>
+    /// <typeparam name="T">事件返回数据类型</typeparam>
+    public interface IEventData<TData, T> : IBaseEventData
+    {
+        /// <summary>
+        /// 发布同步事件
+        /// <para>
+        /// 当存在多个订阅时,只返回第一个订阅结果
+        /// </para></summary>
+        /// <param name="sender">事件源</param>
+        /// <param name="data">事件数据</param>
+        /// <param name="properties">筛选器</param>
+        /// <returns></returns>
+        T Publish(object sender, TData data, Properties? properties = null);
+        /// <summary>
+        /// 发布异步事件
+        /// </summary>
+        Task<T> PublishAsync(object sender, TData data, Properties? properties = null);
+        List<T> PublishList(object sender, TData data, Properties? properties = null);
+        Task<List<T>> PublishListAsync(object sender, TData data, Properties? properties = null);
+        /// <summary>
+        /// 订阅事件
+        /// </summary>
+        /// <param name="func">事件处理函数</param>
+        /// <param name="properties">筛选器</param>
+        Guid Subscrip(Func<object, EventArgs<TData>, T> func, Properties? properties = null);
+        /// <summary>
+        /// 订阅事件
+        /// </summary>
+        /// <param name="func">事件处理函数</param>
+        /// <param name="properties">筛选器</param>
+        Guid SubscripList(Func<object, EventArgs<TData>, List<T>> func, Properties? properties = null);
+
+    }
+}

+ 29 - 0
EventBroker/IEventData{TData}.cs

@@ -0,0 +1,29 @@
+namespace EventBus
+{
+    /// <summary>
+    /// 事件句柄
+    /// </summary>
+    /// <typeparam name="TData">事件发布数据类型</typeparam>
+    public interface IEventData<TData> : IBaseEventData
+    {
+        /// <summary>
+        /// 发布同步事件
+        /// </summary>
+        /// <param name="sender">事件源</param>
+        /// <param name="data">事件数据</param>
+        /// <param name="properties">筛选器</param>
+        void Publish(object sender, TData data, Properties? properties = null);
+        /// <summary>
+        /// 发布异步事件
+        /// </summary>
+        Task PublishAsync(object sender, TData data, Properties? properties = null);
+        /// <summary>
+        /// 订阅事件
+        /// </summary>
+        /// <param name="action">事件处理函数</param>
+        /// <param name="properties">筛选器</param>
+        Guid Subscrip(Action<object, EventArgs<TData>> action, Properties? properties = null);
+
+
+    }
+}

+ 49 - 0
EventBroker/Properties.cs

@@ -0,0 +1,49 @@
+namespace EventBus
+{
+    public sealed class Properties
+    {
+        internal Dictionary<string, string> Filter { get; set; } = new Dictionary<string, string>();
+        public void Add(string name, string value)
+        {
+            if (Filter.TryGetValue(name, out string val)) Filter[name] = value;
+            else Filter.Add(name, value);
+        }
+        public string this[string name]
+        {
+            get
+            {
+                if (Filter.ContainsKey(name)) return Filter[name];
+                else return null;
+            }
+            set
+            {
+                if (!Filter.ContainsKey(name)) Filter.Add(name, value);
+                else Filter[name] = value;
+            }
+        }
+        public bool TryGetValue(string name, out string value) => Filter.TryGetValue(name, out value);
+        public int Count => Filter.Count;
+        public void Remove(string name) => Filter.Remove(name);
+        public void Clear() => Filter.Clear();
+        public IEnumerable<string> Values => Filter.Values;
+        public IEnumerable<string> Names => Filter.Keys;
+        /// <summary>
+        /// 比较两个属性是否相等
+        /// </summary>
+        /// <param name="properties"></param>
+        /// <returns></returns>
+        internal bool Contains(Properties properties)
+        {
+            if (properties == null) return false;
+            if (properties.Count != Count) return false;
+            foreach (var name in Names)
+            {
+                if (!Filter.TryGetValue(name, out string val)) return false;
+                else if (!val.Contains(properties[name])) return false;
+            }
+            return true;
+        }
+
+        public static Properties Default => new Properties();
+    }
+}

+ 29 - 0
EventBroker/PropertiesToolkit.cs

@@ -0,0 +1,29 @@
+namespace EventBus
+{
+    static class PropertiesToolkit
+    {
+        /// <summary>
+        /// 
+        /// </summary>
+        /// <param name="properties"></param>
+        /// <returns></returns>
+        internal static bool FilterRule(this Properties source, Properties properties)
+        {
+            if (source == null) return true;
+            if (source.Count == 0) return true;
+            if (properties == null) properties = Properties.Default;
+            if (source.Names.Intersect(properties.Names).Count() != source.Count) return false;
+            foreach (var name in source.Names)
+            {
+                if (!source.TryGetValue(name, out string val)) return false;
+                else
+                {
+                    string valstr = properties[name];
+                    if (string.IsNullOrEmpty(valstr)) return false;
+                    return val.Contains(valstr);
+                }
+            }
+            return true;
+        }
+    }
+}