Commit 4e2a93fc authored by 阿星Plus's avatar 阿星Plus

😘 事件处理模块

parent 59e9635d
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Runtime.ExceptionServices;
namespace Plus.Collections namespace Plus.Collections
{ {
...@@ -139,5 +142,46 @@ namespace Plus.Collections ...@@ -139,5 +142,46 @@ namespace Plus.Collections
{ {
return dictionary.GetOrAdd(key, k => factory()); return dictionary.GetOrAdd(key, k => factory());
} }
public static Assembly GetAssembly(this Type type)
{
return type.GetTypeInfo().Assembly;
}
public static MethodInfo GetMethod(this Type type, string methodName, int pParametersCount = 0, int pGenericArgumentsCount = 0)
{
return type
.GetMethods()
.Where(m => m.Name == methodName).ToList()
.Select(m => new
{
Method = m,
Params = m.GetParameters(),
Args = m.GetGenericArguments()
})
.Where(x => x.Params.Length == pParametersCount
&& x.Args.Length == pGenericArgumentsCount
).Select(x => x.Method)
.First();
}
/// <summary>
/// Executes given <paramref name="action"/> by locking given <paramref name="source"/> object.
/// </summary>
/// <typeparam name="T">Type of the object (to be locked)</typeparam>
/// <param name="source">Source object (to be locked)</param>
/// <param name="action">Action (to be executed)</param>
public static void Locking<T>(this T source, Action<T> action) where T : class
{
lock (source)
{
action(source);
}
}
public static void ReThrow(this Exception exception)
{
ExceptionDispatchInfo.Capture(exception).Throw();
}
} }
} }
\ No newline at end of file
using Plus.Dependency;
namespace Plus.Configuration.Startup
{
/// <summary>
/// 用于配置 <see cref="IEventBus"/>.
/// </summary>
public interface IEventBusConfiguration
{
/// <summary>
/// True, to use <see cref="EventBus.Default"/>.
/// False, to create per <see cref="IIocManager"/>.
/// This is generally set to true. But, for unit tests,
/// it can be set to false.
/// Default: true.
/// </summary>
bool UseDefaultEventBus { get; set; }
}
}
\ No newline at end of file
...@@ -6,7 +6,7 @@ namespace Plus.Configuration.Startup ...@@ -6,7 +6,7 @@ namespace Plus.Configuration.Startup
/// <summary> /// <summary>
/// 在启动时的模块配置 /// 在启动时的模块配置
/// </summary> /// </summary>
public interface IPlusStartupConfiguration public interface IPlusStartupConfiguration: IDictionaryBasedConfig
{ {
/// <summary> /// <summary>
/// 获取与此配置关联的IOC管理器 /// 获取与此配置关联的IOC管理器
...@@ -26,5 +26,20 @@ namespace Plus.Configuration.Startup ...@@ -26,5 +26,20 @@ namespace Plus.Configuration.Startup
/// <typeparam name="T"></typeparam> /// <typeparam name="T"></typeparam>
/// <returns></returns> /// <returns></returns>
T Get<T>(); T Get<T>();
//IUnitOfWorkDefaultOptions UnitOfWork
//{
// get;
//}
//ICachingConfiguration Caching
//{
// get;
//}
//IValidationConfiguration Validation
//{
// get;
//}
} }
} }
\ No newline at end of file
using Castle.Core.Logging;
using Plus.Collections;
using Plus.Event.Bus.Factories;
using Plus.Event.Bus.Factories.Internals;
using Plus.Event.Bus.Handlers;
using Plus.Event.Bus.Handlers.Internals;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Threading;
using System.Threading.Tasks;
namespace Plus.Event.Bus
{
/// <summary>
/// 以单例模式实现 EventBus
/// </summary>
public class EventBus : IEventBus
{
private class EventTypeWithEventHandlerFactories
{
public Type EventType { get; }
public List<IEventHandlerFactory> EventHandlerFactories { get; }
public EventTypeWithEventHandlerFactories(Type eventType, List<IEventHandlerFactory> eventHandlerFactories)
{
EventType = eventType;
EventHandlerFactories = eventHandlerFactories;
}
}
private readonly ConcurrentDictionary<Type, List<IEventHandlerFactory>> _handlerFactories;
public static EventBus Default { get; } = new EventBus();
public ILogger Logger { get; set; }
public EventBus()
{
_handlerFactories = new ConcurrentDictionary<Type, List<IEventHandlerFactory>>();
Logger = NullLogger.Instance;
}
public IDisposable Register<TEventData>(Action<TEventData> action) where TEventData : IEventData
{
return Register(typeof(TEventData), new ActionEventHandler<TEventData>(action));
}
public IDisposable Register<TEventData>(IEventHandler<TEventData> handler) where TEventData : IEventData
{
return Register(typeof(TEventData), handler);
}
public IDisposable Register<TEventData, THandler>() where TEventData : IEventData where THandler : IEventHandler<TEventData>, new()
{
return Register(typeof(TEventData), new TransientEventHandlerFactory<THandler>());
}
public IDisposable Register(Type eventType, IEventHandler handler)
{
return Register(eventType, new SingleInstanceHandlerFactory(handler));
}
public IDisposable Register<TEventData>(IEventHandlerFactory handlerFactory) where TEventData : IEventData
{
return Register(typeof(TEventData), handlerFactory);
}
public IDisposable Register(Type eventType, IEventHandlerFactory handlerFactory)
{
GetOrCreateHandlerFactories(eventType).Locking(factories => factories.Add(handlerFactory));
return new FactoryUnregistrar(this, eventType, handlerFactory);
}
public void Unregister<TEventData>(Action<TEventData> action) where TEventData : IEventData
{
GetOrCreateHandlerFactories(typeof(TEventData))
.Locking(factories =>
{
factories.RemoveAll(
factory =>
{
if (!(factory is SingleInstanceHandlerFactory singleInstanceFactory))
{
return false;
}
if (!(singleInstanceFactory.HandlerInstance is ActionEventHandler<TEventData> actionHandler))
{
return false;
}
return actionHandler.Action == action;
});
});
}
public void Unregister<TEventData>(IEventHandler<TEventData> handler) where TEventData : IEventData
{
Unregister(typeof(TEventData), handler);
}
public void Unregister(Type eventType, IEventHandler handler)
{
GetOrCreateHandlerFactories(eventType)
.Locking(factories =>
{
factories.RemoveAll(
factory =>
factory is SingleInstanceHandlerFactory &&
(factory as SingleInstanceHandlerFactory).HandlerInstance == handler
);
});
}
public void Unregister<TEventData>(IEventHandlerFactory factory) where TEventData : IEventData
{
Unregister(typeof(TEventData), factory);
}
public void Unregister(Type eventType, IEventHandlerFactory factory)
{
GetOrCreateHandlerFactories(eventType).Locking(factories => factories.Remove(factory));
}
public void UnregisterAll<TEventData>() where TEventData : IEventData
{
UnregisterAll(typeof(TEventData));
}
public void UnregisterAll(Type eventType)
{
GetOrCreateHandlerFactories(eventType).Locking(factories => factories.Clear());
}
public void Trigger<TEventData>(TEventData eventData) where TEventData : IEventData
{
Trigger((object)null, eventData);
}
public void Trigger<TEventData>(object eventSource, TEventData eventData) where TEventData : IEventData
{
Trigger(typeof(TEventData), eventSource, eventData);
}
public void Trigger(Type eventType, IEventData eventData)
{
Trigger(eventType, null, eventData);
}
public void Trigger(Type eventType, object eventSource, IEventData eventData)
{
List<Exception> list = new List<Exception>();
TriggerHandlingException(eventType, eventSource, eventData, list);
if (list.Any())
{
if (list.Count == 1)
{
list[0].ReThrow();
}
throw new AggregateException("More than one error has occurred while triggering the event: " + eventType, list);
}
}
private void TriggerHandlingException(Type eventType, object eventSource, IEventData eventData, List<Exception> exceptions)
{
eventData.EventSource = eventSource;
foreach (EventTypeWithEventHandlerFactories handlerFactory in GetHandlerFactories(eventType))
{
foreach (IEventHandlerFactory eventHandlerFactory in handlerFactory.EventHandlerFactories)
{
IEventHandler handler = eventHandlerFactory.GetHandler();
try
{
if (handler == null)
{
throw new Exception("Registered event handler for event type " + handlerFactory.EventType.Name + " does not implement IEventHandler<" + handlerFactory.EventType.Name + "> interface!");
}
Type type = typeof(IEventHandler<>).MakeGenericType(handlerFactory.EventType);
MethodInfo method = type.GetMethod("HandleEvent", new Type[1]
{
handlerFactory.EventType
});
method.Invoke(handler, new object[1]
{
eventData
});
}
catch (TargetInvocationException ex)
{
exceptions.Add(ex.InnerException);
}
catch (Exception item)
{
exceptions.Add(item);
}
finally
{
eventHandlerFactory.ReleaseHandler(handler);
}
}
}
if (eventType.GetTypeInfo().IsGenericType && eventType.GetGenericArguments().Length == 1 && typeof(IEventDataWithInheritableGenericArgument).IsAssignableFrom(eventType))
{
Type type2 = eventType.GetGenericArguments()[0];
Type baseType = type2.GetTypeInfo().BaseType;
if (baseType != null)
{
Type type3 = eventType.GetGenericTypeDefinition().MakeGenericType(baseType);
object[] constructorArgs = ((IEventDataWithInheritableGenericArgument)eventData).GetConstructorArgs();
IEventData eventData2 = (IEventData)Activator.CreateInstance(type3, constructorArgs);
eventData2.EventTime = eventData.EventTime;
Trigger(type3, eventData.EventSource, eventData2);
}
}
}
private IEnumerable<EventTypeWithEventHandlerFactories> GetHandlerFactories(Type eventType)
{
var list = new List<EventTypeWithEventHandlerFactories>();
foreach (KeyValuePair<Type, List<IEventHandlerFactory>> item in from hf in _handlerFactories
where ShouldTriggerEventForHandler(eventType, hf.Key)
select hf)
{
list.Add(new EventTypeWithEventHandlerFactories(item.Key, item.Value));
}
return list.ToArray();
}
private static bool ShouldTriggerEventForHandler(Type eventType, Type handlerType)
{
if (handlerType == eventType)
{
return true;
}
if (handlerType.IsAssignableFrom(eventType))
{
return true;
}
return false;
}
public Task TriggerAsync<TEventData>(TEventData eventData) where TEventData : IEventData
{
return TriggerAsync((object)null, eventData);
}
public Task TriggerAsync<TEventData>(object eventSource, TEventData eventData) where TEventData : IEventData
{
ExecutionContext.SuppressFlow();
Task result = Task.Factory.StartNew(delegate
{
try
{
Trigger(eventSource, eventData);
}
catch (Exception ex)
{
Logger.Warn(ex.ToString(), ex);
}
});
ExecutionContext.RestoreFlow();
return result;
}
public Task TriggerAsync(Type eventType, IEventData eventData)
{
return TriggerAsync(eventType, null, eventData);
}
public Task TriggerAsync(Type eventType, object eventSource, IEventData eventData)
{
ExecutionContext.SuppressFlow();
Task result = Task.Factory.StartNew(delegate
{
try
{
Trigger(eventType, eventSource, eventData);
}
catch (Exception ex)
{
Logger.Warn(ex.ToString(), ex);
}
});
ExecutionContext.RestoreFlow();
return result;
}
private List<IEventHandlerFactory> GetOrCreateHandlerFactories(Type eventType)
{
return _handlerFactories.GetOrAdd(eventType, (Type type) => new List<IEventHandlerFactory>());
}
}
}
\ No newline at end of file
using Castle.MicroKernel;
using Castle.MicroKernel.Registration;
using Castle.MicroKernel.SubSystems.Configuration;
using Castle.Windsor;
using Plus.Configuration.Startup;
using Plus.Dependency;
using Plus.Event.Bus.Factories;
using Plus.Event.Bus.Handlers;
using System.Reflection;
namespace Plus.Event.Bus
{
/// <summary>
/// 自动注册所有处理程序
/// </summary>
internal class EventBusInstaller : IWindsorInstaller
{
private readonly IIocResolver _iocResolver;
private readonly IEventBusConfiguration _eventBusConfiguration;
private IEventBus _eventBus;
public EventBusInstaller(IIocResolver iocResolver)
{
_iocResolver = iocResolver;
_eventBusConfiguration = iocResolver.Resolve<IEventBusConfiguration>();
}
public void Install(IWindsorContainer container, IConfigurationStore store)
{
if (_eventBusConfiguration.UseDefaultEventBus)
{
container.Register(
Component.For<IEventBus>().Instance(EventBus.Default).LifestyleSingleton()
);
}
else
{
container.Register(
Component.For<IEventBus>().ImplementedBy<EventBus>().LifestyleSingleton()
);
}
_eventBus = container.Resolve<IEventBus>();
container.Kernel.ComponentRegistered += Kernel_ComponentRegistered;
}
private void Kernel_ComponentRegistered(string key, IHandler handler)
{
if (!typeof(IEventHandler).GetTypeInfo().IsAssignableFrom(handler.ComponentModel.Implementation))
{
return;
}
var interfaces = handler.ComponentModel.Implementation.GetTypeInfo().GetInterfaces();
foreach (var @interface in interfaces)
{
if (!typeof(IEventHandler).GetTypeInfo().IsAssignableFrom(@interface))
{
continue;
}
var genericArgs = @interface.GetGenericArguments();
if (genericArgs.Length == 1)
{
_eventBus.Register(genericArgs[0], new IocHandlerFactory(_iocResolver, handler.ComponentModel.Implementation));
}
}
}
}
}
\ No newline at end of file
using Plus.Event.Bus.Handlers;
namespace Plus.Event.Bus.Factories
{
/// <summary>
/// 为负责创建,获取和发布事件处理程序定义的接口
/// </summary>
public interface IEventHandlerFactory
{
/// <summary>
/// 获取事件处理程序
/// </summary>
/// <returns></returns>
IEventHandler GetHandler();
/// <summary>
/// 释放事件处理程序
/// </summary>
/// <param name="handler"></param>
void ReleaseHandler(IEventHandler handler);
}
}
\ No newline at end of file
using System;
namespace Plus.Event.Bus.Factories.Internals
{
/// <summary>
/// Used to unregister a <see cref="IEventHandlerFactory"/> on <see cref="Dispose"/> method.
/// </summary>
internal class FactoryUnregistrar : IDisposable
{
private readonly IEventBus _eventBus;
private readonly Type _eventType;
private readonly IEventHandlerFactory _factory;
public FactoryUnregistrar(IEventBus eventBus, Type eventType, IEventHandlerFactory factory)
{
_eventBus = eventBus;
_eventType = eventType;
_factory = factory;
}
public void Dispose()
{
_eventBus.Unregister(_eventType, _factory);
}
}
}
\ No newline at end of file
using Plus.Event.Bus.Handlers;
namespace Plus.Event.Bus.Factories.Internals
{
/// <summary>
/// This <see cref="IEventHandlerFactory"/> implementation is used to handle events by a single instance object.
/// </summary>
/// <remarks>
/// This class always gets the same single instance of handler.
/// </remarks>
internal class SingleInstanceHandlerFactory : IEventHandlerFactory
{
/// <summary>
/// The event handler instance.
/// </summary>
public IEventHandler HandlerInstance { get; private set; }
/// <summary>
///
/// </summary>
/// <param name="handler"></param>
public SingleInstanceHandlerFactory(IEventHandler handler)
{
HandlerInstance = handler;
}
public IEventHandler GetHandler()
{
return HandlerInstance;
}
public void ReleaseHandler(IEventHandler handler)
{
}
}
}
\ No newline at end of file
using Plus.Event.Bus.Handlers;
using System;
namespace Plus.Event.Bus.Factories.Internals
{
/// <summary>
/// This <see cref="IEventHandlerFactory"/> implementation is used to handle events by a transient instance object.
/// </summary>
/// <remarks>
/// This class always creates a new transient instance of handler.
/// </remarks>
internal class TransientEventHandlerFactory<THandler> : IEventHandlerFactory
where THandler : IEventHandler, new()
{
/// <summary>
/// Creates a new instance of the handler object.
/// </summary>
/// <returns>The handler object</returns>
public IEventHandler GetHandler()
{
return new THandler();
}
public Type GetHandlerType()
{
return typeof(THandler);
}
/// <summary>
/// Disposes the handler object if it's <see cref="IDisposable"/>. Does nothing if it's not.
/// </summary>
/// <param name="handler">Handler to be released</param>
public void ReleaseHandler(IEventHandler handler)
{
if (handler is IDisposable)
{
(handler as IDisposable).Dispose();
}
}
}
}
\ No newline at end of file
using Plus.Dependency;
using Plus.Event.Bus.Handlers;
using System;
namespace Plus.Event.Bus.Factories
{
public class IocHandlerFactory : IEventHandlerFactory
{
private readonly IIocResolver _iocResolver;
public Type HandlerType { get; private set; }
public IocHandlerFactory(IIocResolver iocResolver, Type handlerType)
{
_iocResolver = iocResolver;
HandlerType = handlerType;
}
public IEventHandler GetHandler()
{
return (IEventHandler)_iocResolver.Resolve(HandlerType);
}
public void ReleaseHandler(IEventHandler handler)
{
_iocResolver.Release(handler);
}
}
}
\ No newline at end of file
using System.Threading.Tasks;
namespace Plus.Event.Bus.Handlers
{
/// <summary>
/// 定义一个处理 <see cref="IEventHandler{TEventData}"/> 类型事件的接口。
/// </summary>
/// <typeparam name="TEventData">要处理的事件类型</typeparam>
public interface IAsyncEventHandler<in TEventData> : IEventHandler
{
/// <summary>
/// 实现此方法处理事件
/// </summary>
/// <param name="eventData"></param>
/// <returns></returns>
Task HandleEventAsync(TEventData eventData);
}
}
\ No newline at end of file
namespace Plus.Event.Bus.Handlers
{
/// <summary>
/// 事件处理接口
/// </summary>
public interface IEventHandler
{
}
}
\ No newline at end of file
namespace Plus.Event.Bus.Handlers
{
/// <summary>
/// 定义一个处理 <see cref="IEventHandler{TEventData}"/> 类型事件的接口。
/// </summary>
/// <typeparam name="TEventData">要处理的事件类型</typeparam>
public interface IEventHandler<in TEventData> : IEventHandler
{
/// <summary>
/// 实现此方法处理事件
/// </summary>
/// <param name="eventData">Event data</param>
void HandleEvent(TEventData eventData);
}
}
\ No newline at end of file
using Plus.Dependency;
using System;
namespace Plus.Event.Bus.Handlers.Internals
{
/// <summary>
/// 这个事件处理程序是一个适配器,能够使用一个操作作为 <see cref="IEventHandler{TEventData}"/> 实现
/// </summary>
/// <typeparam name="TEventData">事件类型</typeparam>
internal class ActionEventHandler<TEventData> :
IEventHandler<TEventData>,
ITransientDependency
{
public Action<TEventData> Action { get; private set; }
/// <summary>
/// 创建一个新的 <see cref="ActionEventHandler{TEventData}"/> 实例
/// </summary>
/// <param name="handler"></param>
public ActionEventHandler(Action<TEventData> handler)
{
Action = handler;
}
/// <summary>
/// 处理事件的操作
/// </summary>
/// <param name="eventData"></param>
public void HandleEvent(TEventData eventData)
{
Action(eventData);
}
}
}
\ No newline at end of file
using Plus.Dependency;
using System;
using System.Threading.Tasks;
namespace Plus.Event.Bus.Handlers.Internals
{
/// <summary>
/// 这个事件处理程序是一个适配器,能够使用一个操作作为 <see cref="IAsyncEventHandler{TEventData}"/> 实现
/// </summary>
/// <typeparam name="TEventData">事件类型</typeparam>
internal class AsyncActionEventHandler<TEventData> :
IAsyncEventHandler<TEventData>,
ITransientDependency
{
public Func<TEventData, Task> Action { get; private set; }
/// <summary>
/// 创建一个新的 <see cref="AsyncActionEventHandler{TEventData}"/> 实例
/// </summary>
/// <param name="handler"></param>
public AsyncActionEventHandler(Func<TEventData, Task> handler)
{
Action = handler;
}
/// <summary>
/// 处理事件的操作
/// </summary>
/// <param name="eventData"></param>
/// <returns></returns>
public async Task HandleEventAsync(TEventData eventData)
{
await Action(eventData);
}
}
}
\ No newline at end of file
using Plus.Event.Bus.Factories;
using Plus.Event.Bus.Handlers;
using System;
using System.Threading.Tasks;
namespace Plus.Event.Bus
{
/// <summary>
/// 定义事件接口
/// </summary>
public interface IEventBus
{
IDisposable Register<TEventData>(Action<TEventData> action) where TEventData : IEventData;
IDisposable Register<TEventData>(IEventHandler<TEventData> handler) where TEventData : IEventData;
IDisposable Register<TEventData, THandler>() where TEventData : IEventData where THandler : IEventHandler<TEventData>, new();
IDisposable Register(Type eventType, IEventHandler handler);
IDisposable Register<TEventData>(IEventHandlerFactory handlerFactory) where TEventData : IEventData;
IDisposable Register(Type eventType, IEventHandlerFactory handlerFactory);
void Unregister<TEventData>(Action<TEventData> action) where TEventData : IEventData;
void Unregister<TEventData>(IEventHandler<TEventData> handler) where TEventData : IEventData;
void Unregister(Type eventType, IEventHandler handler);
void Unregister<TEventData>(IEventHandlerFactory factory) where TEventData : IEventData;
void Unregister(Type eventType, IEventHandlerFactory factory);
void UnregisterAll<TEventData>() where TEventData : IEventData;
void UnregisterAll(Type eventType);
void Trigger<TEventData>(TEventData eventData) where TEventData : IEventData;
void Trigger<TEventData>(object eventSource, TEventData eventData) where TEventData : IEventData;
void Trigger(Type eventType, IEventData eventData);
void Trigger(Type eventType, object eventSource, IEventData eventData);
Task TriggerAsync<TEventData>(TEventData eventData) where TEventData : IEventData;
Task TriggerAsync<TEventData>(object eventSource, TEventData eventData) where TEventData : IEventData;
Task TriggerAsync(Type eventType, IEventData eventData);
Task TriggerAsync(Type eventType, object eventSource, IEventData eventData);
}
}
\ No newline at end of file
using System;
namespace Plus.Event.Bus
{
/// <summary>
/// 为所有事件定义接口。
/// </summary>
public interface IEventData
{
/// <summary>
/// 事件发生的时间
/// </summary>
DateTime EventTime { get; set; }
/// <summary>
/// 触发事件的对象
/// </summary>
object EventSource { get; set; }
}
}
\ No newline at end of file
namespace Plus.Event.Bus
{
/// <summary>
/// 此接口必须由具有单个泛型参数的事件数据类实现
/// </summary>
public interface IEventDataWithInheritableGenericArgument
{
/// <summary>
/// 获取创建该类的参数
/// </summary>
/// <returns></returns>
object[] GetConstructorArgs();
}
}
\ No newline at end of file
using System;
namespace Plus
{
/// <summary>
/// 生成GUID接口
/// </summary>
public interface IGuidGenerator
{
/// <summary>
/// 创建GUID
/// </summary>
Guid Create();
}
}
\ No newline at end of file
using Plus.Modules; using Castle.MicroKernel.Registration;
using Plus.Collections;
using Plus.Configuration.Startup;
using Plus.Dependency;
using Plus.Event.Bus;
using Plus.Modules;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Text; using System.IO;
using System.Linq.Expressions;
namespace Plus namespace Plus
{ {
public class PlusLeadershipModule : PlusModule public class PlusLeadershipModule : PlusModule
{ {
public override void PreInitialize()
{
IocManager.AddRegistrar(new BasicConventionalRegistrar());
ConfigureCaches();
AddIgnoredTypes();
AddMethodParameterValidators();
}
public override void Initialize()
{
foreach (Action value in ((PlusStartupConfiguration)Configuration).ServiceReplaceActions.Values)
{
value();
}
IocManager.IocContainer.Install(new EventBusInstaller(IocManager));
IocManager.RegisterAssembly(typeof(PlusLeadershipModule).GetAssembly());
}
public override void PostInitialize()
{
RegisterMissingComponents();
}
public override void Shutdown()
{
}
private void RegisterMissingComponents()
{
if (!IocManager.IsRegistered<IGuidGenerator>())
{
IocManager.IocContainer.Register(
Component
.For<IGuidGenerator, SequentialGuidGenerator>()
.Instance(SequentialGuidGenerator.Instance)
);
}
//IocManager.RegisterIfNot<IUnitOfWork, NullUnitOfWork>(DependencyLifeStyle.Transient);
//IocManager.RegisterIfNot<IUnitOfWorkFilterExecuter, NullUnitOfWorkFilterExecuter>();
}
private void AddMethodParameterValidators()
{
//Configuration.Validation.Validators.Add<DataAnnotationsValidator>();
//Configuration.Validation.Validators.Add<ValidatableObjectValidator>();
}
private void AddIgnoredTypes()
{
var commonIgnoredTypes = new[]
{
typeof(Stream),
typeof(Expression)
};
foreach (var ignoredType in commonIgnoredTypes)
{
//Configuration.Auditing.IgnoredTypes.AddIfNotContains(ignoredType);
//Configuration.Validation.IgnoredTypes.AddIfNotContains(ignoredType);
}
var validationIgnoredTypes = new[] { typeof(Type) };
foreach (var ignoredType in validationIgnoredTypes)
{
//Configuration.Validation.IgnoredTypes.AddIfNotContains(ignoredType);
}
}
private void ConfigureCaches()
{
}
} }
} }
\ No newline at end of file
using System;
namespace Plus
{
public class SequentialGuidGenerator : IGuidGenerator
{
public static SequentialGuidGenerator Instance { get; } = new SequentialGuidGenerator();
public Guid Create()
{
byte[] array = Guid.NewGuid().ToByteArray();
DateTime dateTime = new DateTime(1900, 1, 1);
DateTime now = DateTime.Now;
TimeSpan timeSpan = new TimeSpan(now.Ticks - dateTime.Ticks);
TimeSpan timeOfDay = now.TimeOfDay;
byte[] bytes = BitConverter.GetBytes(timeSpan.Days);
byte[] bytes2 = BitConverter.GetBytes((long)(timeOfDay.TotalMilliseconds / 3.333333));
Array.Reverse(bytes);
Array.Reverse(bytes2);
Array.Copy(bytes, bytes.Length - 2, array, array.Length - 6, 2);
Array.Copy(bytes2, bytes2.Length - 4, array, array.Length - 4, 4);
return new Guid(array);
}
}
}
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment