标签:需要 stat write 反序列化 本地 for line 表示 com
在领域事件中,有时为了数据的一致性,需要先将事件持久化,然后在读取数据时还原并执行事件保证数据一致。
持久化委托时,我们需要持久化委托的类型、方法名称和方法参数类型。
如申明一个委托:
public delegate void DomainEventHandler(object sender, BaseDomainEventArgs eventArgs);
定义一个事件:
public static event DomainEventHandler HelloDomainEvent;
获取事件订阅委托列表,并获取委托的类型、方法名称和方法参数类型
1 foreach (var item in HelloDomainEvent.GetInvocationList())//按照调用顺序返回此多路广播委托的调用列表。
2 {
3 var eventType = item.Target.GetType().AssemblyQualifiedName;//获取当前委托调用者的 System.Type 的程序集限定名,其中包括从中加载 System.Type 的程序集的名称
4 var eventMethodName = item.Method.Name;//获取委托表示方法的名称
5 var eventMethodParamaters = item.Method.GetParameters();//获取委托表示方法的参数
6 String[] eventMethodParamaterTypes = new String[eventMethodParamaters.Length];//委托表示方法的参数类型
7 var index = 0;
8 foreach (var paramater in eventMethodParamaters)
9 {
10 eventMethodParamaterTypes[index] = paramater.ParameterType.AssemblyQualifiedName;//获取参数的System.Type 的程序集限定名,其中包括从中加载 System.Type 的程序集的名称
11 index++;
12 }
13 }
可以将 eventType ,eventMethodName ,eventMethodParamaterTypes 持久化在数据库或本地文件中。
接下来是从持久化库中还原委托:
1 private TDelegator CreateDelegator<TDelegator>(String strEventType,String eventMethodName,String[] strEventMethodParameterTypes)
2 {
3 var eventType = Type.GetType(strEventType); //获得委托调用者类型
4 var target = eventType.Assembly.CreateInstance(eventType.FullName); //实例化委托调用者
5 var targetConstant = Expression.Constant(target, eventType); //创建委托调用常量表达式
6
7 ParameterExpression[] arguments = new ParameterExpression[strEventMethodParameterTypes.Length];//创建参数表达式数组
8
9 var index = 0;
10 foreach (var item in strEventMethodParameterTypes)
11 {
12 arguments[index] = Expression.Parameter(Type.GetType(strEventMethodParameterTypes[index]));//创建参数表达式,并将其赋值给数表达式数组
13 index++;
14 }
15
16 var methodCallExp = Expression.Call(targetConstant, eventType.GetMethod(eventMethodName), arguments);//创建一个表示调用带参数的方法的MethodCallExpression。
17 //Expression.Lambda<TDelegator>(methodCallExp, arguments) 返回以表达式目录树的形式将强类型 lambda 表达式表示为数据结构的 Expression<TDelegate>
18 //Expression<TDelegate>.Compile() 将表达式树描述的 lambda 表达式编译为可执行代码,并生成表示该 lambda 表达式的委托
19 return Expression.Lambda<TDelegator>(methodCallExp, arguments).Compile();
20 }
为了保证数据一致,我们在执行还原的委托时还需要知道当时委托传入的参数,所以在持久化委托时,我们还要获取到委托传入的参数,并持久化。
简单示例:
1 /// <summary>
2 /// 领域事件委托
3 /// </summary>
4 /// <param name="sender"></param>
5 /// <param name="eventArgs"></param>
6 /// <summary>
7 public delegate void DomainEventHandler(object sender, BaseDomainEventArgs eventArgs);
8 public class DomainEventTest2 : BaseTest
9 {
10 /// 事件
11 /// </summary>
12 public static event DomainEventHandler HelloDomainEvent;
13
14 private List<Dictionary<String, Object>> eventStort = new List<Dictionary<string, Object>>();//事件及调用参数持久化
15
16 public override void Test()
17 {
18 var chinaSayHelloHandler = new ChinaSayHelloHandler();
19 var englishSayHelloHandler = new EnglishSayHelloHandler();
20 {
21 HelloDomainEvent += chinaSayHelloHandler.Handler;
22 HelloDomainEvent += englishSayHelloHandler.Handler;
23 WriteLine("持久化事件中。。。");
24 Persistence(HelloDomainEvent, new SayEventArgs() { Message = "在见面时打招呼" });
25 WriteLine("持久化事件完成");
26 }
27 {
28 WriteLine("加载并执行事件中。。。");
29 foreach (var item in eventStort)
30 {
31 object objEventType = null;
32 object objEventMethodName = null;
33 object objEventMethodParamaterTypes = null;
34 object objEventArgs = null;
35 item.TryGetValue("eventType", out objEventType);
36 item.TryGetValue("eventMethodName", out objEventMethodName);
37
38 item.TryGetValue("eventMethodParamaterTypes", out objEventMethodParamaterTypes);//如为JSon格式还需反序列化成原来对象
39 item.TryGetValue("eventArgs", out objEventArgs);//如为JSon格式还需反序列化成原来对象
40
41 var delegator = CreateDelegator<DomainEventHandler>(objEventType.ToString(),objEventMethodName.ToString(),objEventMethodParamaterTypes as String[]);
42 var eventType = Type.GetType(objEventType.ToString()); //获得委托调用者类型
43 var target = eventType.Assembly.CreateInstance(eventType.FullName); //实例化委托调用者
44 delegator(eventType, objEventArgs as BaseDomainEventArgs);
45 }
46 WriteLine("加载并执行事件完成");
47 }
48 }
49
50 private void Persistence(DomainEventHandler DomainEvent, BaseDomainEventArgs eventArgs)
51 {
52 foreach (var item in HelloDomainEvent.GetInvocationList())//按照调用顺序返回此多路广播委托的调用列表。
53 {
54 var dic = new Dictionary<String, Object>();
55 var eventType = item.Target.GetType().AssemblyQualifiedName;//获取当前委托调用者的 System.Type 的程序集限定名,其中包括从中加载 System.Type 的程序集的名称
56 var eventMethodName = item.Method.Name;//获取委托表示方法的名称
57 var eventMethodParamaters = item.Method.GetParameters();//获取委托表示方法的参数
58 String[] eventMethodParamaterTypes = new String[eventMethodParamaters.Length];//委托表示方法的参数类型
59 var index = 0;
60 foreach (var paramater in eventMethodParamaters)
61 {
62 eventMethodParamaterTypes[index] = paramater.ParameterType.AssemblyQualifiedName;//获取参数的System.Type 的程序集限定名,其中包括从中加载 System.Type 的程序集的名称
63 index++;
64 }
65 dic.Add("eventType", eventType);
66 dic.Add("eventMethodName", eventMethodName);
67 dic.Add("eventMethodParamaterTypes", eventMethodParamaterTypes);//可转为JSon格式保存
68 dic.Add("eventArgs", eventArgs);//可转为JSon格式保存
69 eventStort.Add(dic);
70 }
71 }
72
73 private TDelegator CreateDelegator<TDelegator>(String strEventType, String eventMethodName, String[] strEventMethodParameterTypes)
74 {
75 var eventType = Type.GetType(strEventType); //获得委托调用者类型
76 var target = eventType.Assembly.CreateInstance(eventType.FullName); //实例化委托调用者
77 var targetConstant = Expression.Constant(target, eventType); //创建委托调用常量表达式
78
79 ParameterExpression[] arguments = new ParameterExpression[strEventMethodParameterTypes.Length];//创建参数表达式数组
80
81 var index = 0;
82 foreach (var item in strEventMethodParameterTypes)
83 {
84 arguments[index] = Expression.Parameter(Type.GetType(strEventMethodParameterTypes[index]));//创建参数表达式,并将其赋值给数表达式数组
85 index++;
86 }
87
88 var methodCallExp = Expression.Call(targetConstant, eventType.GetMethod(eventMethodName), arguments);//创建一个表示调用带参数的方法的MethodCallExpression。
89 //Expression.Lambda<TDelegator>(methodCallExp, arguments) 返回以表达式目录树的形式将强类型 lambda 表达式表示为数据结构的 Expression<TDelegate>
90 //Expression<TDelegate>.Compile() 将表达式树描述的 lambda 表达式编译为可执行代码,并生成表示该 lambda 表达式的委托
91 return Expression.Lambda<TDelegator>(methodCallExp, arguments).Compile();
92 }
93 }
/// <summary>
/// 领域事件参数
/// </summary>
public abstract class BaseDomainEventArgs: EventArgs
{
}
1 /// <summary>
2 /// 领域事件处理
3 /// </summary>
4 public abstract class BaseDomainEventHandler
5 {
6 public abstract void Handler(object sender, BaseDomainEventArgs eventArgs);
7 }
public class SayEventArgs: BaseDomainEventArgs
{
private String message;
public String Message { get { return message; } set { message = value.ToUpper(); } }
}
public class ChinaSayHelloHandler : BaseDomainEventHandler
{
public override void Handler(object sender, BaseDomainEventArgs eventArgs)
{
SayEventArgs sayEventArgs = (SayEventArgs)eventArgs;
Console.WriteLine("{0}:中国说你好", sayEventArgs.Message);
}
}
public class EnglishSayHelloHandler : BaseDomainEventHandler
{
public override void Handler(object sender, BaseDomainEventArgs eventArgs)
{
SayEventArgs sayEventArgs = (SayEventArgs)eventArgs;
Console.WriteLine("{0}:English Say Hello", sayEventArgs.Message);
}
}
public class ChinaSayByeByeHandler : BaseDomainEventHandler
{
public override void Handler(object sender, BaseDomainEventArgs eventArgs)
{
SayEventArgs sayEventArgs = (SayEventArgs)eventArgs;
Console.WriteLine("{0}:中国说再见", sayEventArgs.Message);
}
}
public class EnglishSyeByeBayHandler : BaseDomainEventHandler
{
public override void Handler(object sender, BaseDomainEventArgs eventArgs)
{
SayEventArgs sayEventArgs = (SayEventArgs)eventArgs;
Console.WriteLine("{0}:English Say Bye Bye", sayEventArgs.Message);
}
}
执行结果:

标签:需要 stat write 反序列化 本地 for line 表示 com
原文地址:http://www.cnblogs.com/801234567com/p/6900655.html