├── .gitignore ├── Basf.sln ├── Basf ├── AppRuntime.cs ├── Basf.csproj ├── Container │ ├── AopMatcher.cs │ ├── IAbsfRegistration.cs │ ├── IObjectContainer.cs │ ├── LifetimeStyle.cs │ └── ObjectContainerExtensions.cs ├── Data │ └── ActionResponse.cs ├── Domain │ ├── IAggRoot.cs │ ├── IAggRootEventHandler.cs │ ├── IAggRootState.cs │ ├── IAggRootStorage.cs │ ├── ICommand.cs │ ├── IDomainContext.cs │ ├── IDomainEvent.cs │ └── IUnitOfWork.cs ├── Logging │ └── ILogger.cs ├── Mq │ ├── IConsumer.cs │ ├── IConsumerManager.cs │ ├── IMessageHandler.cs │ ├── IProducer.cs │ └── Message.cs ├── Properties │ └── PublishProfiles │ │ └── FolderProfile.pubxml ├── Serializing │ ├── IBinarySerializer.cs │ ├── IJsonSerializer.cs │ └── ISerializer.cs └── Utilities │ ├── CityHash.cs │ └── uint128.cs └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | obj 2 | bin 3 | build 4 | packages 5 | 6 | *.suo 7 | *.user 8 | *.sln.cache 9 | *.nupkg 10 | *.testsettings 11 | *.vsmdi -------------------------------------------------------------------------------- /Basf.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 15 4 | VisualStudioVersion = 15.0.26403.3 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Basf", "Basf\Basf.csproj", "{180D00C7-F0C0-48D9-9E86-331C6D426167}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|Any CPU = Debug|Any CPU 11 | Release|Any CPU = Release|Any CPU 12 | EndGlobalSection 13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 14 | {180D00C7-F0C0-48D9-9E86-331C6D426167}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 15 | {180D00C7-F0C0-48D9-9E86-331C6D426167}.Debug|Any CPU.Build.0 = Debug|Any CPU 16 | {180D00C7-F0C0-48D9-9E86-331C6D426167}.Release|Any CPU.ActiveCfg = Release|Any CPU 17 | {180D00C7-F0C0-48D9-9E86-331C6D426167}.Release|Any CPU.Build.0 = Release|Any CPU 18 | EndGlobalSection 19 | GlobalSection(SolutionProperties) = preSolution 20 | HideSolutionNode = FALSE 21 | EndGlobalSection 22 | EndGlobal 23 | -------------------------------------------------------------------------------- /Basf/AppRuntime.cs: -------------------------------------------------------------------------------- 1 | using Basf.Logging; 2 | using System; 3 | 4 | namespace Basf 5 | { 6 | public sealed class AppRuntime 7 | { 8 | #region 私有字段 9 | private static AppRuntime Instance = new AppRuntime(); 10 | private IObjectContainer objContainer = null; 11 | 12 | //private List 13 | #endregion 14 | 15 | #region 构造方法 16 | static AppRuntime() 17 | { 18 | } 19 | private AppRuntime() 20 | { 21 | } 22 | #endregion 23 | 24 | #region 属性 25 | public static IObjectContainer Container => AppRuntime.Instance.objContainer; 26 | public static ILogger Logger = (ILogger)AppRuntime.Container?.Resolve(typeof(ILogger)); 27 | #endregion 28 | 29 | #region 配置方法 30 | public static void Configure(Action objBuilder) 31 | { 32 | objBuilder?.Invoke(AppRuntime.Instance); 33 | } 34 | //public AppRuntime MatchInterceptor(InterceptorMatchKind kind, string expression, Type interceptorType) 35 | //{ 36 | // if (objContainer == null) throw new ArgumentNullException("objContainer"); 37 | // AppRuntime.Container = objContainer; 38 | // return AppRuntime.Instance; 39 | //} 40 | //public AppRuntime MatchInterceptor(InterceptorMatchKind kind, string expression, string interceptorName) 41 | //{ 42 | // if (objContainer == null) throw new ArgumentNullException("Container"); 43 | // AppRuntime.Container = objContainer; 44 | // return AppRuntime.Instance; 45 | //} 46 | public AppRuntime UsingContainer(IObjectContainer container) 47 | { 48 | if (container == null) throw new ArgumentNullException("container"); 49 | AppRuntime.Instance.objContainer = container; 50 | return AppRuntime.Instance; 51 | } 52 | public AppRuntime UsingLogger() where TLogger : class, ILogger 53 | { 54 | if (AppRuntime.Container == null) throw new ArgumentNullException("AppRuntime.Container"); 55 | AppRuntime.Container.RegisterType(LifetimeStyle.Singleton); 56 | return AppRuntime.Instance; 57 | } 58 | #endregion 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /Basf/Basf.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | net45;net451;net46;net461;net462;netstandard1.6 4 | True 5 | leaf kevin 6 | https://github.com/leafkevin/Basf 7 | false 8 | false 9 | false 10 | 1.1.0.0 11 | 1.1.0.0 12 | 1.1.0.0 13 | 一个DDD+CQRS+Event Sourcing通用框架的接口,可以很容易的结合各种现有成熟框架来搭建。CQRS可以结合Orleans,Akka.net等Actor框架封装实现。目前支持.NET 4.5+,.NET Standard1.6+。 14 | 一个DDD+CQRS+Event Sourcing通用框架的接口,可以很容易的结合各种现有成熟框架来搭建。CQRS可以结合Orleans,Akka.net等Actor框架封装实现。目前支持.NET 4.5+,.NET Standard1.6+。 15 | 16 | 17 | $(DefineConstants);COREFX 18 | 19 | 20 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /Basf/Container/AopMatcher.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Basf 4 | { 5 | public class AopMatcher 6 | { 7 | public AopMatchKind Kind { get; set; } 8 | public string Expression { get; set; } 9 | public Type InterceptorType { get; set; } 10 | } 11 | public enum AopMatchKind 12 | { 13 | ClassName = 1, 14 | InterfaceName = 2, 15 | AssignableFrom = 3, 16 | MethodName = 4 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /Basf/Container/IAbsfRegistration.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | 4 | namespace Basf 5 | { 6 | public interface IAbsfRegistration 7 | { 8 | bool HasInterceptor { get; } 9 | IAbsfRegistrationTypeExpression RegisterType(Type objServiceType, Type objComponentType); 10 | IAbsfRegistrationTypeExpression RegisterType() where TService : class; 11 | IAbsfRegistrationTypeExpression RegisterType(Type objServiceType); 12 | IAbsfRegistrationInstanceExpression RegisterType(TService objInstance) where TService : class; 13 | IAbsfRegistrationTypeExpression RegisterType() 14 | where TService : class 15 | where TComponent : class, TService; 16 | IAbsfRegistrationGenericExpression RegisterGeneric(Type objService, Type objComponent); 17 | } 18 | public interface IAbsfRegistrationTypeExpression 19 | { 20 | IAbsfRegistrationTypeExpression Forward(); 21 | IAbsfRegistrationTypeExpression Forward(); 22 | IAbsfRegistrationTypeExpression Forward(); 23 | IAbsfRegistrationTypeExpression Forward(params Type[] objServiceTypes); 24 | IAbsfRegistrationTypeExpression Named(string strName); 25 | IAbsfRegistrationTypeExpression Named(string strName, Type objServiceType); 26 | IAbsfRegistrationTypeExpression Lifetime(LifetimeStyle iLifetimeStyle); 27 | IAbsfRegistrationTypeExpression OwnedLifetime(Type objServiceType); 28 | IAbsfRegistrationTypeExpression OwnedLifetime(); 29 | IAbsfRegistrationTypeExpression UsingConstructor(params Type[] objTypes); 30 | IAbsfRegistrationTypeExpression WithParameter(string strName, object objValue); 31 | IAbsfRegistrationTypeExpression WithParameters(params object[] objParamters); 32 | IAbsfRegistrationTypeExpression WithParameters(IDictionary objParamters); 33 | IAbsfRegistrationTypeExpression WithInterfaceInterceptor(Type interceptorType); 34 | IAbsfRegistrationTypeExpression WithClassInterceptor(Type interceptorType); 35 | } 36 | public interface IAbsfRegistrationTypeExpression 37 | { 38 | IAbsfRegistrationTypeExpression Forward(); 39 | IAbsfRegistrationTypeExpression Forward(); 40 | IAbsfRegistrationTypeExpression Forward(); 41 | IAbsfRegistrationTypeExpression Forward(params Type[] objServiceTypes); 42 | IAbsfRegistrationTypeExpression Named(string strName); 43 | IAbsfRegistrationTypeExpression Named(string strName, Type objServiceType); 44 | IAbsfRegistrationTypeExpression Lifetime(LifetimeStyle iLifetimeStyle); 45 | IAbsfRegistrationTypeExpression OwnedLifetime(Type objServiceType); 46 | IAbsfRegistrationTypeExpression OwnedLifetime(); 47 | IAbsfRegistrationTypeExpression UsingConstructor(params Type[] objTypes); 48 | IAbsfRegistrationTypeExpression WithParameter(string strName, object objValue); 49 | IAbsfRegistrationTypeExpression WithParameters(params object[] objParamters); 50 | IAbsfRegistrationTypeExpression WithParameters(IDictionary objParamters); 51 | IAbsfRegistrationTypeExpression WithInterfaceInterceptor(Type interceptorType); 52 | IAbsfRegistrationTypeExpression WithClassInterceptor(Type interceptorType); 53 | } 54 | public interface IAbsfRegistrationInstanceExpression 55 | { 56 | IAbsfRegistrationInstanceExpression Forward(); 57 | IAbsfRegistrationInstanceExpression Forward(); 58 | IAbsfRegistrationInstanceExpression Forward(); 59 | IAbsfRegistrationInstanceExpression Forward(params Type[] objServiceTypes); 60 | IAbsfRegistrationInstanceExpression Named(string strName); 61 | IAbsfRegistrationInstanceExpression Named(string strName, Type objServiceType); 62 | IAbsfRegistrationInstanceExpression Lifetime(LifetimeStyle iLifetimeStyle); 63 | IAbsfRegistrationInstanceExpression OwnedLifetime(Type objServiceType); 64 | IAbsfRegistrationInstanceExpression OwnedLifetime(); 65 | IAbsfRegistrationInstanceExpression WithInterfaceInterceptor(Type interceptorType); 66 | } 67 | public interface IAbsfRegistrationGenericExpression 68 | { 69 | IAbsfRegistrationGenericExpression Forward(); 70 | IAbsfRegistrationGenericExpression Forward(); 71 | IAbsfRegistrationGenericExpression Forward(); 72 | IAbsfRegistrationGenericExpression Forward(params Type[] objServiceTypes); 73 | IAbsfRegistrationGenericExpression Lifetime(LifetimeStyle iLifetimeStyle); 74 | IAbsfRegistrationGenericExpression OwnedLifetime(Type objServiceType); 75 | IAbsfRegistrationGenericExpression OwnedLifetime(); 76 | IAbsfRegistrationGenericExpression UsingConstructor(params Type[] objTypes); 77 | IAbsfRegistrationGenericExpression WithParameter(string strName, object objValue); 78 | IAbsfRegistrationGenericExpression WithParameters(params object[] objParamters); 79 | IAbsfRegistrationGenericExpression WithParameters(IDictionary objParamters); 80 | IAbsfRegistrationGenericExpression WithInterfaceInterceptor(Type interceptorType); 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /Basf/Container/IObjectContainer.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | 4 | namespace Basf 5 | { 6 | public interface IObjectContainer : IDisposable 7 | { 8 | #region ServiceRegistry组件注册 9 | void Register(Action objRegisterBuilder); 10 | #endregion 11 | 12 | #region ServiceFetcher组件获取 13 | object Resolve(Type objServiceType, params object[] objArgs); 14 | object Resolve(Type objServiceType, IDictionary objArgs); 15 | TService ResolveNamed(string strName, params object[] objArgs) where TService : class; 16 | TService ResolveNamed(string strName, IDictionary objArgs) where TService : class; 17 | IEnumerable ResolveAll(Type objServiceType); 18 | IEnumerable ResolveAll() where TService : class; 19 | #endregion 20 | 21 | #region Other 22 | bool HasRegister(Type objServiceType, string strName = null); 23 | #endregion 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /Basf/Container/LifetimeStyle.cs: -------------------------------------------------------------------------------- 1 | namespace Basf 2 | { 3 | public enum LifetimeStyle 4 | { 5 | /// 6 | /// 单件 7 | /// 8 | Singleton, 9 | /// 10 | /// 线程内单件 11 | /// 12 | Thread, 13 | /// 14 | /// 瞬态 15 | /// 16 | Transient, 17 | /// 18 | /// 作用域 19 | /// 20 | Scoped, 21 | /// 22 | /// 对象池 23 | /// 24 | Pool, 25 | /// 26 | /// 请求 27 | /// 28 | Request 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /Basf/Container/ObjectContainerExtensions.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | 4 | namespace Basf 5 | { 6 | public static class ObjectContainerExtensions 7 | { 8 | #region Register 9 | public static void RegisterType(this IObjectContainer objContainer, Type objServiceType, Type objComponentType) 10 | { 11 | objContainer.Register(f => f.RegisterType(objServiceType, objComponentType)); 12 | } 13 | public static void RegisterType(this IObjectContainer objContainer, Type objServiceType, Type objComponentType, string strName) 14 | { 15 | objContainer.Register(f => f.RegisterType(objServiceType, objComponentType).Named(strName, objServiceType)); 16 | } 17 | public static void RegisterType(this IObjectContainer objContainer, Type objServiceType, Type objComponentType, LifetimeStyle iLifetimeStyle) 18 | { 19 | objContainer.Register(f => f.RegisterType(objServiceType, objComponentType).Lifetime(iLifetimeStyle)); 20 | } 21 | public static void RegisterType(this IObjectContainer objContainer, Type objServiceType, Type objComponentType, string strName, LifetimeStyle iLifetimeStyle) 22 | { 23 | objContainer.Register(f => f.RegisterType(objServiceType, objComponentType).Named(strName, objServiceType).Lifetime(iLifetimeStyle)); 24 | } 25 | public static void RegisterType(this IObjectContainer objContainer) where TService : class 26 | { 27 | objContainer.Register(f => f.RegisterType()); 28 | } 29 | public static void RegisterType(this IObjectContainer objContainer, string strName) where TService : class 30 | { 31 | objContainer.Register(f => f.RegisterType().Named(strName)); 32 | } 33 | public static void RegisterType(this IObjectContainer objContainer, LifetimeStyle iLifetimeStyle) where TService : class 34 | { 35 | objContainer.Register(f => f.RegisterType().Lifetime(iLifetimeStyle)); 36 | } 37 | public static void RegisterType(this IObjectContainer objContainer, string strName, LifetimeStyle iLifetimeStyle) where TService : class 38 | { 39 | objContainer.Register(f => f.RegisterType().Named(strName).Lifetime(iLifetimeStyle)); 40 | } 41 | public static void RegisterType(this IObjectContainer objContainer) 42 | where TService : class 43 | where TComponent : class, TService 44 | { 45 | objContainer.Register(f => f.RegisterType()); 46 | } 47 | public static void RegisterType(this IObjectContainer objContainer, string strName) 48 | where TService : class 49 | where TComponent : class, TService 50 | { 51 | objContainer.Register(f => f.RegisterType().Named(strName)); 52 | } 53 | public static void RegisterType(this IObjectContainer objContainer, LifetimeStyle iLifetimeStyle) 54 | where TService : class 55 | where TComponent : class, TService 56 | { 57 | objContainer.Register(f => f.RegisterType().Lifetime(iLifetimeStyle)); 58 | } 59 | public static void RegisterType(this IObjectContainer objContainer, string strName, LifetimeStyle iLifetimeStyle) 60 | where TService : class 61 | where TComponent : class, TService 62 | { 63 | objContainer.Register(f => f.RegisterType().Named(strName).Lifetime(iLifetimeStyle)); 64 | } 65 | public static void RegisterInstance(this IObjectContainer objContainer, TService objInstance) where TService : class 66 | { 67 | objContainer.Register(f => f.RegisterType(objInstance)); 68 | } 69 | public static void RegisterInstance(this IObjectContainer objContainer, TService objInstance, string strName) where TService : class 70 | { 71 | objContainer.Register(f => f.RegisterType(objInstance).Named(strName)); 72 | } 73 | public static void RegisterInstance(this IObjectContainer objContainer, TService objInstance, LifetimeStyle iLifetimeStyle) where TService : class 74 | { 75 | objContainer.Register(f => f.RegisterType(objInstance).Lifetime(iLifetimeStyle)); 76 | } 77 | public static void RegisterInstance(this IObjectContainer objContainer, TService objInstance, string strName, LifetimeStyle iLifetimeStyle) where TService : class 78 | { 79 | objContainer.Register(f => f.RegisterType(objInstance).Named(strName).Lifetime(iLifetimeStyle)); 80 | } 81 | public static void RegisterGeneric(this IObjectContainer objContainer, Type objService, Type objComponent) 82 | { 83 | objContainer.Register(f => f.RegisterGeneric(objService, objComponent).Lifetime(LifetimeStyle.Transient)); 84 | } 85 | public static void RegisterGeneric(this IObjectContainer objContainer, Type objService, Type objComponent, LifetimeStyle iLifetimeStyle) 86 | { 87 | objContainer.Register(f => f.RegisterGeneric(objService, objComponent).Lifetime(iLifetimeStyle)); 88 | } 89 | #endregion 90 | 91 | #region Resolve 92 | public static TService Resolve(this IObjectContainer objContainer, params object[] objArgs) where TService : class 93 | { 94 | return (TService)objContainer.Resolve(typeof(TService), objArgs); 95 | } 96 | public static TService Resolve(this IObjectContainer objContainer, IDictionary objArgs) where TService : class 97 | { 98 | return (TService)objContainer.Resolve(typeof(TService), objArgs); 99 | } 100 | public static bool HasRegister(this IObjectContainer objContainer) 101 | { 102 | return objContainer.HasRegister(typeof(TService)); 103 | } 104 | public static bool HasRegister(this IObjectContainer objContainer, string strName) 105 | { 106 | return objContainer.HasRegister(typeof(TService), strName); 107 | } 108 | #endregion 109 | } 110 | } 111 | -------------------------------------------------------------------------------- /Basf/Data/ActionResponse.cs: -------------------------------------------------------------------------------- 1 | namespace Basf.Data 2 | { 3 | public class ActionResponse 4 | { 5 | private static readonly ActionResponse successResponse = new ActionResponse(true); 6 | public bool IsSuccess { get; set; } 7 | public int Code { get; set; } 8 | public string Message { get; set; } 9 | public static ActionResponse Success { get { return successResponse; } } 10 | protected ActionResponse(bool isSuccess, int code = 0, string message = null) 11 | { 12 | this.IsSuccess = isSuccess; 13 | this.Code = code; 14 | this.Message = message; 15 | } 16 | public static ActionResponse Succeed(T result = default(T)) 17 | { 18 | return new ActionResponse(true, result); 19 | } 20 | public static ActionResponse Fail(int code, string message) 21 | { 22 | return new ActionResponse(false, code, message); 23 | } 24 | public static ActionResponse Fail(int code, string message) 25 | { 26 | return new ActionResponse(false, code, message, default(T)); 27 | } 28 | } 29 | public class ActionResponse : ActionResponse 30 | { 31 | public T Result { get; private set; } 32 | internal protected ActionResponse(bool isSuccess, T result) 33 | : base(isSuccess) 34 | { 35 | this.Result = result; 36 | } 37 | internal protected ActionResponse(bool isSuccess, int code, string message, T result) 38 | : base(isSuccess, code, message) 39 | { 40 | this.Result = result; 41 | } 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /Basf/Domain/IAggRoot.cs: -------------------------------------------------------------------------------- 1 | namespace Basf.Domain 2 | { 3 | public interface IAggRoot 4 | { 5 | TKey UniqueId { get; } 6 | int Version { get; } 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /Basf/Domain/IAggRootEventHandler.cs: -------------------------------------------------------------------------------- 1 | namespace Basf.Domain 2 | { 3 | public interface IAggRootEventHandler 4 | { 5 | void HandleEvent(IAggRootState state, TDomainEvent domainEvent) where TDomainEvent : IDomainEvent; 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /Basf/Domain/IAggRootState.cs: -------------------------------------------------------------------------------- 1 | namespace Basf.Domain 2 | { 3 | public interface IAggRootState 4 | { 5 | TKey UniqueId { get; } 6 | int Version { get; } 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /Basf/Domain/IAggRootStorage.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Threading.Tasks; 3 | 4 | namespace Basf.Domain 5 | { 6 | public interface IAggRootStorage where TAggRootState : IAggRootState 7 | { 8 | Task Get(TKey aggRootId, int version) where TEvent : IDomainEvent; 9 | Task Add(TEvent domainEvent) where TEvent : IDomainEvent; 10 | Task>> Find(TKey aggRootId, int startVersion); 11 | Task> Find(TKey aggRootId, string eventType, int startVersion) where TEvent : IDomainEvent; 12 | Task>> Find(string commandId); 13 | Task> Find(string commandId, string eventType) where TEvent : IDomainEvent; 14 | Task Complete(TEvent domainEvent) where TEvent : IDomainEvent; 15 | Task GetSnapshot(TKey aggRootId); 16 | Task SaveSnapshot(TAggRootState state); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /Basf/Domain/ICommand.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Basf.Domain 4 | { 5 | public interface ICommand 6 | { 7 | string UniqueId { get; } 8 | DateTime Timestamp { get; } 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /Basf/Domain/IDomainContext.cs: -------------------------------------------------------------------------------- 1 | using System.Threading.Tasks; 2 | 3 | namespace Basf.Domain 4 | { 5 | public interface IDomainContext 6 | { 7 | Task Create(TKey id) where TEntity : IAggRoot; 8 | Task Get(TKey id) where TEntity : IAggRoot; 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /Basf/Domain/IDomainEvent.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Basf.Domain 4 | { 5 | public interface IDomainEvent 6 | { 7 | string UniqueId { get; } 8 | string CommandId { get; } 9 | string EventType { get; } 10 | TKey AggRootId { get; set; } 11 | int Version { get; set; } 12 | DateTime Timestamp { get; } 13 | } 14 | public interface IDomainEvent : IDomainEvent 15 | { 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /Basf/Domain/IUnitOfWork.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Basf.Domain 4 | { 5 | public interface IUnitOfWork : IDisposable 6 | { 7 | void Begin(); 8 | void Commit(); 9 | void Rollback(); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /Basf/Logging/ILogger.cs: -------------------------------------------------------------------------------- 1 | namespace Basf.Logging 2 | { 3 | public interface ILogger 4 | { 5 | void Debug(string message); 6 | void Debug(string format, params object[] objArgs); 7 | void Info(string message); 8 | void Info(string strFormat, params object[] objArgs); 9 | void Error(string message); 10 | void Error(string strFormat, params object[] objArgs); 11 | void Warn(string message); 12 | void Warn(string strFormat, params object[] objArgs); 13 | void Fatal(string message); 14 | void Fatal(string strFormat, params object[] objArgs); 15 | } 16 | } -------------------------------------------------------------------------------- /Basf/Mq/IConsumer.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Threading.Tasks; 3 | 4 | namespace Basf.Mq 5 | { 6 | public interface IConsumer 7 | { 8 | void Subscribe(string routingKey); 9 | Task Execute(Message msg); 10 | void AddHandler(string msgType, Func handler); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /Basf/Mq/IConsumerManager.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Basf.Mq 4 | { 5 | public interface IConsumerManager 6 | { 7 | void Start(); 8 | void RegisterConsumer(string routingKey, Type consumerType); 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /Basf/Mq/IMessageHandler.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Threading.Tasks; 3 | 4 | namespace Basf.Mq 5 | { 6 | public interface IMessageHandler 7 | { 8 | string RoutingKey { get; } 9 | Task Execute(Message msg); 10 | string AddProcesser(string msgType, Func msgProcesser); 11 | } 12 | public interface IMessageHandler 13 | { 14 | string RoutingKey { get; } 15 | Task Execute(Message msg); 16 | string AddProcesser(string msgType, Func msgProcesser); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /Basf/Mq/IProducer.cs: -------------------------------------------------------------------------------- 1 | namespace Basf.Mq 2 | { 3 | public interface IProducer 4 | { 5 | void Publish(string exchange, string routingKey, Message msg); 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /Basf/Mq/Message.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | 4 | namespace Basf.Mq 5 | { 6 | public class Message 7 | { 8 | public string CommandId { get; set; } 9 | public DateTime Timestamp { get; set; } = DateTime.Now; 10 | public string MessageType { get; set; } 11 | public Dictionary Context { get; set; } 12 | public TBody Body { get; set; } 13 | } 14 | public class Message : Message 15 | { 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /Basf/Properties/PublishProfiles/FolderProfile.pubxml: -------------------------------------------------------------------------------- 1 |  2 | 6 | 7 | 8 | FileSystem 9 | Release 10 | net45 11 | bin\Release\PublishOutput 12 | 13 | -------------------------------------------------------------------------------- /Basf/Serializing/IBinarySerializer.cs: -------------------------------------------------------------------------------- 1 | namespace Basf.Serializing 2 | { 3 | public interface IBinarySerializer: ISerializer 4 | { 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /Basf/Serializing/IJsonSerializer.cs: -------------------------------------------------------------------------------- 1 | namespace Basf.Serializing 2 | { 3 | public interface IJsonSerializer : ISerializer 4 | { 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /Basf/Serializing/ISerializer.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Basf.Serializing 4 | { 5 | public interface ISerializer 6 | { 7 | T Serialize(object obj); 8 | object Deserialize(T value, Type type); 9 | TObject Deserialize(T value) where TObject : class; 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /Basf/Utilities/CityHash.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | #if !COREFX 3 | using System.Runtime; 4 | #endif 5 | using System.Runtime.CompilerServices; 6 | using System.Text; 7 | 8 | namespace Basf.Utilities 9 | { 10 | /// 11 | /// CityHash provides hash functions for stringsThe functions mix the 12 | /// input bits thoroughly but are not suitable for cryptography. 13 | /// 14 | /// 15 | /// This class can be inherited and it exposes some internal functions (if you want to have fun) 16 | /// 17 | public class CityHash 18 | { 19 | #region 私有常量 20 | // Some primes between 2^63 and 2^64 for various uses. 21 | private const ulong k0 = 0xc3a5c85c97cb3127UL; 22 | private const ulong k1 = 0xb492b66fbe98f273UL; 23 | private const ulong k2 = 0x9ae16a3b2f90404fUL; 24 | 25 | // Magic numbers for 32-bit hashing Copied from Murmur3. 26 | private const uint c1 = 0xcc9e2d51; 27 | private const uint c2 = 0x1b873593; 28 | #endregion 29 | 30 | #region 公共方法 31 | /// 32 | /// Computes a 32-bit city hash for the specified string. 33 | /// 34 | /// The string value. 35 | /// A 32-bit city hash. 36 | /// This function encodes the string using the unicode block (ISO/IEC 8859-1). 37 | public static uint CityHash32(string value) 38 | { 39 | return CityHash32(Encoding.GetEncoding("ISO-8859-1").GetBytes(value)); 40 | } 41 | /// 42 | /// Computes the 64-bit city hash for the specified string. 43 | /// 44 | /// The string value. 45 | /// The 64-bit city hash. 46 | /// This function encodes the string using the unicode block (ISO/IEC 8859-1). 47 | public static ulong CityHash64(string value) 48 | { 49 | return CityHash64(Encoding.GetEncoding("ISO-8859-1").GetBytes(value)); 50 | } 51 | /// 52 | /// Computes the 64-bit city hash for the specified string and seed. 53 | /// 54 | /// The string value. 55 | /// The seed used by the algorithm. 56 | /// The 64-bit city hash. 57 | /// This function encodes the string using the unicode block (ISO/IEC 8859-1). 58 | public static ulong CityHash64(string value, ulong seed) 59 | { 60 | return CityHash64(Encoding.GetEncoding("ISO-8859-1").GetBytes(value), k2, seed); 61 | } 62 | /// 63 | /// Computes the 64-bit city hash for the specified string and seed. 64 | /// 65 | /// The string value. 66 | /// The low-order 64-bits seed used by the algorithm. 67 | /// The high-order 64-bits seed used by the algorithm. 68 | /// The 64-bit city hash. 69 | /// This function encodes the string using the unicode block (ISO/IEC 8859-1). 70 | public static ulong CityHash64(string value, ulong seed0, ulong seed1) 71 | { 72 | return CityHash64(Encoding.GetEncoding("ISO-8859-1").GetBytes(value), seed0, seed1); 73 | } 74 | /// 75 | /// Computes the 128-bit city hash and are tuned for strings of at least a few hundred bytes. 76 | /// 77 | /// The string value. 78 | /// The 128-bit city hash. 79 | /// This function encodes the string using the unicode block (ISO/IEC 8859-1). 80 | #if !COREFX 81 | [TargetedPatchingOptOut("Performance critical to inline across NGen image boundaries.")] 82 | #endif 83 | public static uint128 CityHash128(string value) 84 | { 85 | return CityHash128(Encoding.GetEncoding("ISO-8859-1").GetBytes(value)); 86 | } 87 | /// 88 | /// Computes the 128-bit city hash and are tuned for strings of at least a few hundred bytes using 89 | /// the specified . 90 | /// 91 | /// The string value. 92 | /// The seed used by the city hash algorithm. 93 | /// The 128-bit city hash. 94 | /// This function encodes the string using the unicode block (ISO/IEC 8859-1). 95 | #if !COREFX 96 | [TargetedPatchingOptOut("Performance critical to inline across NGen image boundaries.")] 97 | #endif 98 | public static uint128 CityHash128(string value, uint128 seed) 99 | { 100 | return CityHash128(Encoding.GetEncoding("ISO-8859-1").GetBytes(value), seed, 0); 101 | } 102 | #endregion 103 | 104 | #region 私有方法 105 | /// 106 | /// A 32-bit to 32-bit integer hash copied from Murmur3. 107 | /// 108 | private static uint FMix(uint h) 109 | { 110 | h ^= h >> 16; 111 | h *= 0x85ebca6b; 112 | h ^= h >> 13; 113 | h *= 0xc2b2ae35; 114 | h ^= h >> 16; 115 | return h; 116 | } 117 | /// 118 | /// Bitwise right rotate 119 | /// Normally this will compile to a single instruction, especially if the shift is a manifest constant. 120 | /// 121 | #if !COREFX 122 | [TargetedPatchingOptOut("Performance critical to inline across NGen image boundaries.")] 123 | #endif 124 | private static ulong Rotate(ulong val, int shift) 125 | { 126 | // Avoid shifting by 64: doing so yields an undefined result. 127 | return shift == 0 ? val : ((val >> shift) | (val << (64 - shift))); 128 | } 129 | #if !COREFX 130 | [TargetedPatchingOptOut("Performance critical to inline across NGen image boundaries.")] 131 | #endif 132 | private static uint Rotate32(uint value, int shift) 133 | { 134 | return shift == 0 ? value : ((value >> shift) | (value << (32 - shift))); 135 | } 136 | [MethodImpl(MethodImplOptions.AggressiveInlining)] 137 | private static uint Mur(uint a, uint h) 138 | { 139 | // Helper from Murmur3 for combining two 32-bit values. 140 | a *= c1; 141 | a = Rotate32(a, 17); 142 | a *= c2; 143 | h ^= a; 144 | h = Rotate32(h, 19); 145 | return h * 5 + 0xe6546b64; 146 | } 147 | #if !COREFX 148 | [TargetedPatchingOptOut("Performance critical to inline across NGen image boundaries.")] 149 | #endif 150 | private static uint BSwap32(uint value) 151 | { 152 | return 153 | (value >> 24) | 154 | (value & 0x00ff0000) >> 8 | 155 | (value & 0x0000ff00) << 8 | 156 | (value << 24); 157 | } 158 | #if !COREFX 159 | [TargetedPatchingOptOut("Performance critical to inline across NGen image boundaries.")] 160 | #endif 161 | private static ulong BSwap64(ulong value) 162 | { 163 | return 164 | (value >> 56) | 165 | (value & 0x00ff000000000000) >> 40 | 166 | (value & 0x0000ff0000000000) >> 24 | 167 | (value & 0x000000ff00000000) >> 8 | 168 | (value & 0x00000000ff000000) << 8 | 169 | (value & 0x0000000000ff0000) << 24 | 170 | (value & 0x000000000000ff00) << 40 | 171 | (value << 56); 172 | } 173 | /// 174 | /// Returns a 32-bit unsigned integer converted from four bytes at a specified position in a byte array. 175 | /// 176 | /// An array of bytes. 177 | /// The starting position within value. 178 | /// A 32-bit unsigned integer formed by four bytes beginning at . 179 | [MethodImpl(MethodImplOptions.AggressiveInlining)] 180 | #if !COREFX 181 | [TargetedPatchingOptOut("Performance critical to inline across NGen image boundaries.")] 182 | #endif 183 | private static uint Fetch32(byte[] value, int index = 0) 184 | { 185 | return BitConverter.ToUInt32(value, index); 186 | } 187 | /// 188 | /// Returns a 32-bit unsigned integer converted from four bytes at a specified position in a byte array. 189 | /// 190 | /// An array of bytes. 191 | /// The starting position within value. 192 | /// A 32-bit unsigned integer formed by four bytes beginning at . 193 | [MethodImpl(MethodImplOptions.AggressiveInlining)] 194 | #if !COREFX 195 | [TargetedPatchingOptOut("Performance critical to inline across NGen image boundaries.")] 196 | #endif 197 | private static uint Fetch32(byte[] value, uint index = 0) 198 | { 199 | return BitConverter.ToUInt32(value, (int)index); 200 | } 201 | /// 202 | /// Returns a 64-bit unsigned integer converted from eight bytes at a specified position in a byte array. 203 | /// 204 | /// An array of bytes. 205 | /// The starting position within . 206 | /// A 64-bit unsigned integer formed by the eight bytes beginning at . 207 | #if !COREFX 208 | [TargetedPatchingOptOut("Performance critical to inline across NGen image boundaries.")] 209 | #endif 210 | private static ulong Fetch64(byte[] value, int index = 0) 211 | { 212 | return BitConverter.ToUInt64(value, index); 213 | } 214 | [MethodImpl(MethodImplOptions.AggressiveInlining)] 215 | private static uint Hash32Len0to4(byte[] value) 216 | { 217 | var l = (uint)value.Length; 218 | var b = 0u; 219 | var c = 9u; 220 | for (var i = 0; i < l; i++) 221 | { 222 | b = b * c1 + (uint)((sbyte)value[i]); 223 | c ^= b; 224 | } 225 | return FMix(Mur(b, Mur(l, c))); 226 | } 227 | [MethodImpl(MethodImplOptions.AggressiveInlining)] 228 | private static uint Hash32Len5to12(byte[] value) 229 | { 230 | uint a = (uint)value.Length, b = a * 5, c = 9, d = b; 231 | 232 | a += Fetch32(value, 0); 233 | b += Fetch32(value, value.Length - 4); 234 | c += Fetch32(value, (value.Length >> 1) & 4); 235 | 236 | return FMix(Mur(c, Mur(b, Mur(a, d)))); 237 | } 238 | [MethodImpl(MethodImplOptions.AggressiveInlining)] 239 | private static uint Hash32Len13to24(byte[] value) 240 | { 241 | var a = Fetch32(value, (value.Length >> 1) - 4); 242 | var b = Fetch32(value, 4); 243 | var c = Fetch32(value, value.Length - 8); 244 | var d = Fetch32(value, value.Length >> 1); 245 | var e = Fetch32(value, 0); 246 | var f = Fetch32(value, value.Length - 4); 247 | var h = (uint)value.Length; 248 | 249 | return FMix(Mur(f, Mur(e, Mur(d, Mur(c, Mur(b, Mur(a, h))))))); 250 | } 251 | [MethodImpl(MethodImplOptions.AggressiveInlining)] 252 | #if !COREFX 253 | [TargetedPatchingOptOut("Performance critical to inline across NGen image boundaries.")] 254 | #endif 255 | private static void Permute3(ref T a, ref T b, ref T c) 256 | { 257 | var temp = a; 258 | a = c; c = b; b = temp; 259 | } 260 | #if !COREFX 261 | [TargetedPatchingOptOut("Performance critical to inline across NGen image boundaries.")] 262 | #endif 263 | private static ulong ShiftMix(ulong val) 264 | { 265 | return val ^ (val >> 47); 266 | } 267 | #if !COREFX 268 | [TargetedPatchingOptOut("Performance critical to inline across NGen image boundaries.")] 269 | #endif 270 | private static void Swap(ref T a, ref T b) 271 | { 272 | var temp = a; 273 | a = b; 274 | b = temp; 275 | } 276 | /// 277 | /// A subroutine for CityHash128() Returns a decent 128-bit hash for strings 278 | /// of any length representable in signed long Based on City and Murmur. 279 | /// 280 | [MethodImpl(MethodImplOptions.AggressiveInlining)] 281 | protected static uint128 CityMurmur(byte[] value, uint128 seed, int offset) 282 | { 283 | var a = seed.Low; 284 | var b = seed.High; 285 | ulong c; 286 | ulong d; 287 | 288 | var len = value.Length - offset; 289 | var l = len - 16; 290 | 291 | if (l <= 0) 292 | { // len <= 16 293 | a = ShiftMix(a * k1) * k1; 294 | c = b * k1 + HashLen0to16(value, offset); 295 | d = ShiftMix(a + (len >= 8 ? Fetch64(value, offset) : c)); 296 | } 297 | else 298 | { // len > 16 299 | 300 | c = HashLen16(Fetch64(value, offset + len - 8) + k1, a); 301 | d = HashLen16(b + (ulong)len, c + Fetch64(value, offset + len - 16)); 302 | a += d; 303 | 304 | var p = offset; 305 | do 306 | { 307 | a ^= ShiftMix(Fetch64(value, p) * k1) * k1; 308 | a *= k1; 309 | b ^= a; 310 | c ^= ShiftMix(Fetch64(value, p + 8) * k1) * k1; 311 | c *= k1; 312 | d ^= c; 313 | 314 | p += 16; 315 | l -= 16; 316 | } while (l > 0); 317 | 318 | } 319 | a = HashLen16(a, c); 320 | b = HashLen16(d, b); 321 | return new uint128(a ^ b, HashLen16(b, a)); 322 | } 323 | /// 324 | /// Computes a 32-bit city hash for the given encoded string. 325 | /// 326 | /// The string value. 327 | /// A 32-bit city hash. 328 | /// value 329 | /// 330 | /// The city hash is designed to compute hash for STRINGs only! 331 | /// The city hash "works" with other types of data, but keep in mind it was not built for it. 332 | /// 333 | protected internal static uint CityHash32(byte[] value) 334 | { 335 | if (value == null) 336 | throw new ArgumentNullException("value"); 337 | 338 | var len = (uint)value.Length; 339 | 340 | if (len <= 4) 341 | return Hash32Len0to4(value); 342 | 343 | if (len <= 12) 344 | return Hash32Len5to12(value); 345 | 346 | if (len <= 24) 347 | return Hash32Len13to24(value); 348 | 349 | // len > 24 350 | uint h = len, g = c1 * len, f = g; 351 | { 352 | uint a0 = Rotate32(Fetch32(value, len - 4) * c1, 17) * c2; 353 | uint a1 = Rotate32(Fetch32(value, len - 8) * c1, 17) * c2; 354 | uint a2 = Rotate32(Fetch32(value, len - 16) * c1, 17) * c2; 355 | uint a3 = Rotate32(Fetch32(value, len - 12) * c1, 17) * c2; 356 | uint a4 = Rotate32(Fetch32(value, len - 20) * c1, 17) * c2; 357 | 358 | h ^= a0; 359 | h = Rotate32(h, 19); 360 | h = h * 5 + 0xe6546b64; 361 | h ^= a2; 362 | h = Rotate32(h, 19); 363 | h = h * 5 + 0xe6546b64; 364 | 365 | g ^= a1; 366 | g = Rotate32(g, 19); 367 | g = g * 5 + 0xe6546b64; 368 | g ^= a3; 369 | g = Rotate32(g, 19); 370 | g = g * 5 + 0xe6546b64; 371 | 372 | f += a4; 373 | f = Rotate32(f, 19); 374 | f = f * 5 + 0xe6546b64; 375 | } 376 | 377 | for (var i = 0; i < (len - 1) / 20; i++) 378 | { 379 | var a0 = Rotate32(Fetch32(value, 20 * i) * c1, 17) * c2; 380 | var a1 = Fetch32(value, 20 * i + 4); 381 | var a2 = Rotate32(Fetch32(value, 20 * i + 8) * c1, 17) * c2; 382 | var a3 = Rotate32(Fetch32(value, 20 * i + 12) * c1, 17) * c2; 383 | var a4 = Fetch32(value, 20 * i + 16); 384 | 385 | h ^= a0; 386 | h = Rotate32(h, 18); 387 | h = h * 5 + 0xe6546b64; 388 | 389 | f += a1; 390 | f = Rotate32(f, 19); 391 | f = f * c1; 392 | 393 | g += a2; 394 | g = Rotate32(g, 18); 395 | g = g * 5 + 0xe6546b64; 396 | 397 | h ^= a3 + a1; 398 | h = Rotate32(h, 19); 399 | h = h * 5 + 0xe6546b64; 400 | 401 | g ^= a4; 402 | g = BSwap32(g) * 5; 403 | 404 | h += a4 * 5; 405 | h = BSwap32(h); 406 | 407 | f += a0; 408 | 409 | Permute3(ref f, ref h, ref g); 410 | } 411 | 412 | g = Rotate32(g, 11) * c1; 413 | g = Rotate32(g, 17) * c1; 414 | 415 | f = Rotate32(f, 11) * c1; 416 | f = Rotate32(f, 17) * c1; 417 | 418 | h = Rotate32(h + g, 19); 419 | h = h * 5 + 0xe6546b64; 420 | h = Rotate32(h, 17) * c1; 421 | 422 | h = Rotate32(h + f, 19); 423 | h = h * 5 + 0xe6546b64; 424 | h = Rotate32(h, 17) * c1; 425 | 426 | return h; 427 | } 428 | /// 429 | /// Computes the 64-bit city hash for the encoded string. 430 | /// 431 | /// The encoded string. 432 | /// The 64-bit city hash. 433 | /// 434 | /// The city hash is designed to compute hash for STRINGs only! 435 | /// The city hash "works" with other types of data, but keep in mind it was not built for it. 436 | /// 437 | protected internal static ulong CityHash64(byte[] value) 438 | { 439 | if (value.Length <= 16) 440 | return HashLen0to16(value); 441 | 442 | if (value.Length <= 32) 443 | return HashLen17to32(value); 444 | 445 | if (value.Length <= 64) 446 | return HashLen33to64(value); 447 | 448 | // For strings over 64 bytes we hash the end first, and then as we 449 | // loop we keep 56 bytes of state: v, w, x, y, and z. 450 | 451 | var x = Fetch64(value, value.Length - 40); 452 | var y = Fetch64(value, value.Length - 16) + Fetch64(value, value.Length - 56); 453 | var z = HashLen16( 454 | Fetch64(value, value.Length - 48) + (ulong)value.Length, 455 | Fetch64(value, value.Length - 24)); 456 | 457 | var v = WeakHashLen32WithSeeds(value, value.Length - 64, (ulong)value.Length, z); 458 | var w = WeakHashLen32WithSeeds(value, value.Length - 32, y + k1, x); 459 | 460 | x = x * k1 + Fetch64(value); 461 | 462 | // Decrease len to the nearest multiple of 64, and operate on 64-byte chunks. 463 | 464 | var pos = 0; 465 | var len = (value.Length) - 1 & ~63; 466 | do 467 | { 468 | x = Rotate(x + y + v.Low + Fetch64(value, pos + 8), 37) * k1; 469 | y = Rotate(y + v.High + Fetch64(value, pos + 48), 42) * k1; 470 | x ^= w.High; 471 | y += v.Low + Fetch64(value, pos + 40); 472 | z = Rotate(z + w.Low, 33) * k1; 473 | v = WeakHashLen32WithSeeds(value, pos, v.High * k1, x + w.Low); 474 | w = WeakHashLen32WithSeeds(value, pos + 32, z + w.High, y + Fetch64(value, pos + 16)); 475 | Swap(ref z, ref x); 476 | 477 | pos += 64; 478 | len -= 64; 479 | } while (len != 0); 480 | 481 | return HashLen16(HashLen16(v.Low, w.Low) + ShiftMix(y) * k1 + z, HashLen16(v.High, w.High) + x); 482 | } 483 | /// 484 | /// Computes the 64-bit city hash for the specified string and seed. 485 | /// 486 | /// The encoded string. 487 | /// The seed used by the algorithm. 488 | /// The 64-bit city hash. 489 | protected static ulong CityHash64(byte[] value, ulong seed) 490 | { 491 | return CityHash64(value, k2, seed); 492 | } 493 | /// 494 | /// Computes the 64-bit city hash for the specified string and seed. 495 | /// 496 | /// The encoded string. 497 | /// The low-order 64-bits seed used by the algorithm. 498 | /// The high-order 64-bits seed used by the algorithm. 499 | /// The 64-bit city hash. 500 | protected static ulong CityHash64(byte[] value, ulong seed0, ulong seed1) 501 | { 502 | return HashLen16(CityHash64(value) - seed0, seed1); 503 | } 504 | /// 505 | /// Computes a 128-bit city hash for the given encoded string. 506 | /// 507 | /// The encoded string. 508 | /// The 128-bit city hash. 509 | /// 510 | /// The city hash is designed to compute hash for STRINGs only! 511 | /// The city hash "works" with other types of data, but keep in mind it was not built for it. 512 | /// 513 | #if !COREFX 514 | [TargetedPatchingOptOut("Performance critical to inline across NGen image boundaries.")] 515 | #endif 516 | protected static uint128 CityHash128(byte[] value) 517 | { 518 | return value.Length >= 16 519 | ? CityHash128(value, new uint128(Fetch64(value), Fetch64(value, 8) + k0), 16) 520 | : CityHash128(value, new uint128(k0, k1), 0); 521 | } 522 | /// 523 | /// Computes the 128-bit city hash and are tuned for strings of at least a few hundred bytes using 524 | /// the specified starting at a position. 525 | /// 526 | /// The encoded string. 527 | /// The seed used by the hash alrorithm. 528 | /// The offset position in the byte array. 529 | /// The 128-bit city hash. 530 | /// 531 | /// The city hash is designed to compute hash for STRINGs only! 532 | /// The city hash "works" with other types of data, but keep in mind it was not built for it. 533 | /// 534 | [MethodImpl(MethodImplOptions.AggressiveInlining)] 535 | protected static uint128 CityHash128(byte[] value, uint128 seed, int offset) 536 | { 537 | if (value.Length - offset < 128) 538 | return CityMurmur(value, seed, offset); 539 | 540 | // We expect len >= 128 to be the common case Keep 56 bytes of state: 541 | // v, w, x, y, and z. 542 | var len = value.Length - offset; 543 | var x = seed.Low; 544 | var y = seed.High; 545 | var z = (ulong)len * k1; 546 | var v = new uint128 547 | { 548 | Low = Rotate(seed.High ^ k1, 49) * k1 + Fetch64(value, offset) 549 | }; 550 | v.High = Rotate(v.Low, 42) * k1 + Fetch64(value, offset + 8); 551 | 552 | var w = new uint128 553 | { 554 | Low = Rotate(y + z, 35) * k1 + x, 555 | High = Rotate(seed.Low + Fetch64(value, offset + 88), 53) * k1 556 | }; 557 | 558 | 559 | // This is the same inner loop as CityHash64(), manually unrolled. 560 | var s = offset; 561 | do 562 | { 563 | x = Rotate(x + y + v.Low + Fetch64(value, s + 8), 37) * k1; 564 | y = Rotate(y + v.High + Fetch64(value, s + 48), 42) * k1; 565 | x ^= w.High; 566 | y += v.Low + Fetch64(value, s + 40); 567 | z = Rotate(z + w.Low, 33) * k1; 568 | v = WeakHashLen32WithSeeds(value, s, v.High * k1, x + w.Low); 569 | w = WeakHashLen32WithSeeds(value, s + 32, z + w.High, y + Fetch64(value, s + 16)); 570 | 571 | Swap(ref z, ref x); 572 | 573 | s += 64; 574 | 575 | x = Rotate(x + y + v.Low + Fetch64(value, s + 8), 37) * k1; 576 | y = Rotate(y + v.High + Fetch64(value, s + 48), 42) * k1; 577 | x ^= w.High; 578 | y += v.Low + Fetch64(value, s + 40); 579 | z = Rotate(z + w.Low, 33) * k1; 580 | v = WeakHashLen32WithSeeds(value, s, v.High * k1, x + w.Low); 581 | w = WeakHashLen32WithSeeds(value, s + 32, z + w.High, y + Fetch64(value, s + 16)); 582 | 583 | Swap(ref z, ref x); 584 | 585 | s += 64; 586 | len -= 128; 587 | } while (len >= 128); 588 | 589 | x += Rotate(v.Low + z, 49) * k0; 590 | y = y * k0 + Rotate(w.High, 37); 591 | z = z * k0 + Rotate(w.Low, 27); 592 | w.Low *= 9; 593 | v.Low *= k0; 594 | 595 | // If 0 < len < 128, hash up to 4 chunks of 32 bytes each from the end of s. 596 | for (var tail = 0; tail < len;) 597 | { 598 | tail += 32; 599 | 600 | y = Rotate(x + y, 42) * k0 + v.High; 601 | w.Low += Fetch64(value, s + len - tail + 16); 602 | x = x * k0 + w.Low; 603 | z += w.High + Fetch64(value, s + len - tail); 604 | w.High += v.Low; 605 | v = WeakHashLen32WithSeeds(value, s + len - tail, v.Low + z, v.High); 606 | v.Low *= k0; 607 | } 608 | 609 | 610 | // At this point our 56 bytes of state should contain more than 611 | // enough information for a strong 128-bit hash We use two 612 | // different 56-byte-to-8-byte hashes to get a 16-byte final result. 613 | x = HashLen16(x, v.Low); 614 | y = HashLen16(y + z, w.Low); 615 | 616 | return new uint128 617 | { 618 | Low = HashLen16(x + v.High, w.High) + y, 619 | High = HashLen16(x + w.High, y + v.High) 620 | }; 621 | } 622 | [MethodImpl(MethodImplOptions.AggressiveInlining)] 623 | private static ulong HashLen16(ulong u, ulong v) 624 | { 625 | return Hash128to64(new uint128(u, v)); 626 | } 627 | [MethodImpl(MethodImplOptions.AggressiveInlining)] 628 | private static ulong HashLen16(ulong u, ulong v, ulong mul) 629 | { 630 | // Murmur-inspired hashing. 631 | var a = (u ^ v) * mul; 632 | a ^= (a >> 47); 633 | var b = (v ^ a) * mul; 634 | b ^= (b >> 47); 635 | b *= mul; 636 | return b; 637 | } 638 | [MethodImpl(MethodImplOptions.AggressiveInlining)] 639 | private static ulong HashLen0to16(byte[] value, int offset = 0) 640 | { 641 | var len = (uint)(value.Length - offset); 642 | 643 | if (len >= 8) 644 | { 645 | 646 | var mul = k2 + (ulong)len * 2; 647 | var a = Fetch64(value, offset) + k2; 648 | var b = Fetch64(value, value.Length - 8); 649 | var c = Rotate(b, 37) * mul + a; 650 | var d = (Rotate(a, 25) + b) * mul; 651 | 652 | return HashLen16(c, d, mul); 653 | } 654 | 655 | if (len >= 4) 656 | { 657 | var mul = k2 + (ulong)len * 2; 658 | ulong a = Fetch32(value, offset); 659 | return HashLen16(len + (a << 3), Fetch32(value, (int)(offset + len - 4)), mul); 660 | } 661 | 662 | if (len > 0) 663 | { 664 | var a = value[offset]; 665 | var b = value[offset + (len >> 1)]; 666 | var c = value[offset + (len - 1)]; 667 | 668 | var y = a + ((uint)b << 8); 669 | var z = len + ((uint)c << 2); 670 | 671 | return ShiftMix((y * k2 ^ z * k0)) * k2; 672 | } 673 | 674 | return k2; 675 | } 676 | /// 677 | /// This probably works well for 16-byte strings as well, but it may be overkill in that case. 678 | /// 679 | [MethodImpl(MethodImplOptions.AggressiveInlining)] 680 | private static ulong HashLen17to32(byte[] value) 681 | { 682 | var len = (ulong)value.Length; 683 | 684 | var mul = k2 + len * 2ul; 685 | var a = Fetch64(value) * k1; 686 | var b = Fetch64(value, 8); 687 | var c = Fetch64(value, value.Length - 8) * mul; 688 | var d = Fetch64(value, value.Length - 16) * k2; 689 | 690 | return HashLen16(Rotate(a + b, 43) + Rotate(c, 30) + d, a + Rotate(b + k2, 18) + c, mul); 691 | } 692 | /// 693 | /// Return an 8-byte hash for 33 to 64 bytes. 694 | /// 695 | [MethodImpl(MethodImplOptions.AggressiveInlining)] 696 | private static UInt64 HashLen33to64(byte[] value) 697 | { 698 | var mul = k2 + (ulong)value.Length * 2ul; 699 | var a = Fetch64(value) * k2; 700 | var b = Fetch64(value, 8); 701 | var c = Fetch64(value, value.Length - 24); 702 | var d = Fetch64(value, value.Length - 32); 703 | var e = Fetch64(value, 16) * k2; 704 | var f = Fetch64(value, 24) * 9; 705 | var g = Fetch64(value, value.Length - 8); 706 | var h = Fetch64(value, value.Length - 16) * mul; 707 | 708 | var u = Rotate(a + g, 43) + (Rotate(b, 30) + c) * 9; 709 | var v = ((a + g) ^ d) + f + 1; 710 | var w = BSwap64((u + v) * mul) + h; 711 | var x = Rotate(e + f, 42) + c; 712 | var y = (BSwap64((v + w) * mul) + g) * mul; 713 | var z = e + f + c; 714 | 715 | a = BSwap64((x + z) * mul + y) + b; 716 | b = ShiftMix((z + a) * mul + d + h) * mul; 717 | return b + x; 718 | } 719 | [MethodImpl(MethodImplOptions.AggressiveInlining)] 720 | private static ulong Hash128to64(uint128 x) 721 | { 722 | const ulong kMul = 0x9ddfea08eb382d69UL; 723 | 724 | var a = (x.Low ^ x.High) * kMul; 725 | a ^= (a >> 47); 726 | 727 | var b = (x.High ^ a) * kMul; 728 | b ^= (b >> 47); 729 | b *= kMul; 730 | 731 | return b; 732 | } 733 | /// 734 | /// Return a 16-byte hash for 48 bytesQuick and dirty. 735 | /// Callers do best to use "random-looking" values for a and b. 736 | /// 737 | private static uint128 WeakHashLen32WithSeeds(ulong w, ulong x, ulong y, ulong z, ulong a, ulong b) 738 | { 739 | a += w; 740 | b = Rotate(b + a + z, 21); 741 | 742 | var c = a; 743 | a += x; 744 | a += y; 745 | 746 | b += Rotate(a, 44); 747 | 748 | return new uint128(a + z, b + c); 749 | } 750 | #if !COREFX 751 | [TargetedPatchingOptOut("Performance critical to inline across NGen image boundaries.")] 752 | #endif 753 | private static uint128 WeakHashLen32WithSeeds(byte[] value, int offset, ulong a, ulong b) 754 | { 755 | return WeakHashLen32WithSeeds( 756 | Fetch64(value, offset), 757 | Fetch64(value, offset + 8), 758 | Fetch64(value, offset + 16), 759 | Fetch64(value, offset + 24), 760 | a, 761 | b); 762 | } 763 | #endregion 764 | } 765 | } -------------------------------------------------------------------------------- /Basf/Utilities/uint128.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Basf.Utilities 4 | { 5 | /// 6 | /// Represents a 128-bit unsigned integer. 7 | /// 8 | public struct uint128 : IEquatable 9 | { 10 | /// 11 | /// Initializes a new instance of the struct. 12 | /// 13 | public uint128(ulong low, ulong high) 14 | : this() 15 | { 16 | Low = low; 17 | High = high; 18 | } 19 | /// 20 | /// Gets or sets the low-order 64-bits. 21 | /// 22 | /// The low-order 64-bits. 23 | public ulong Low { get; set; } 24 | /// 25 | /// Gets or sets the high-order 64-bits. 26 | /// 27 | /// The high-order 64-bits. 28 | public ulong High { get; set; } 29 | /// 30 | /// Indicates whether the current object is equal to another object of the same type. 31 | /// 32 | /// 33 | /// true if the current object is equal to the parameter; otherwise, false. 34 | /// 35 | /// An object to compare with this object. 36 | public bool Equals(uint128 other) 37 | { 38 | return Low == other.Low && High == other.High; 39 | } 40 | /// 41 | /// Indicates whether this instance and a specified object are equal. 42 | /// 43 | /// 44 | /// true if and this instance are the same type and represent the same value; otherwise, false. 45 | /// 46 | /// Another object to compare to. 47 | public override bool Equals(object obj) 48 | { 49 | if (ReferenceEquals(null, obj)) return false; 50 | return obj is uint128 && Equals((uint128)obj); 51 | } 52 | /// 53 | /// Returns the hash code for this instance. 54 | /// 55 | /// 56 | /// A 32-bit signed integer that is the hash code for this instance. 57 | /// 58 | public override int GetHashCode() 59 | { 60 | unchecked 61 | { 62 | return (Low.GetHashCode() * 397) ^ High.GetHashCode(); 63 | } 64 | } 65 | } 66 | } -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Basf 2 | 一个DDD+CQRS+Event Sourcing通用框架的接口,可以很容易的结合各种现有成熟框架来搭建。CQRS可以结合Orleans,Akka.net等Actor框架封装实现。 3 | 目前支持.NET 4.61+,.NET Standard1.6+。 4 | 5 | --------------------------------------------------------------------------------