接下来,我们实现这个接口,并用Dapper将事件数据保存到SQL Server中。出于框架设计的考虑,我们新建一个Net Standard Class Library项目,在这个新的项目中实现IEventStore接口,这么做的原因已经在上文中介绍过了。代码如下:
public class DapperEventStore : IEventStore
{
private readonly string connectionString;
public DapperEventStore( string connectionString)
{
this .connectionString = connectionString;
}
public async Task SaveEventAsync<TEvent>(TEvent @ event ) where TEvent : IEvent
{
const string sql = @"INSERT INTO [dbo].[Events]
([EventId], [EventPayload], [EventTimestamp])
VALUES
(@eventId, @eventPayload, @eventTimestamp)" ;
using ( var connection = new SqlConnection( this .connectionString))
{
await connection.ExecuteAsync(sql, new
{
eventId = @ event .Id,
eventPayload = JsonConvert.SerializeObject(@ event ),
eventTimestamp = @ event .Timestamp
});
}
}
#region IDisposable Support
// 此处省略
#endregion
}
IDisposable接口的实现部分暂且省略,可以看到,实现还是非常简单的:通过构造函数传入的连接字符串,在SaveEventAsyc方法中,基于SqlConnection对象执行Dapper的扩展方法来完成事件数据的保存。
Note: 此处使用了JsonConvert.SerializeObject方法来序列化事件对象,也就意味着DapperEventStore程序集需要依赖Newtonsoft.Json程序集。虽然在我们此处的案例中不会有什么影响,但这样做会造成DapperEventStore对Newtonsoft.Json的强依赖,这样的依赖关系不仅让DapperEventStore变得不可测试,而且Newtonsoft.Json将来未知的变化,也会影响到DapperEventStore,带来一些不确定性和维护性问题。更好的做法是,引入一个IMessageSerializer接口,在另一个新的程序集中使用Newtonsoft.Json来实现这个接口,同时仅让DapperEventStore依赖IMessageSerializer,并在应用程序启动时,将Newtonsoft.Json的实现注册到IoC容器中。此时,IMessageSerializer可以被Mock,DapperEventStore就变得可测试了;另一方面,由于只有那个新的程序集会依赖Newtonsoft.Json,因此,Newtonsoft.Json的变化也仅仅会影响那个新的程序集,不会对框架主体的其它部分造成任何影响。
本文来自电脑杂谈,转载请注明本文网址:
https://www.pc-fly.com/a/jisuanjixue/article-60185-2.html
>3
来而不往非礼也