如何透明地处理多个存储后端

时间:2011-03-09 12:24:08

标签: nhibernate domain-driven-design event-listener

我正在使用一个应用程序,它现在使用第三方API来处理一些批处理电子邮件相关的任务,为了使它能够工作,我们需要在这个服务中存储一些信息。不幸的是,这些信息(姓/名,电子邮件地址)也是我们想要在我们的应用程序中使用的东西。我的正常倾向是选择一个规范数据源并坚持使用它,但每次我想查找这些字段时往返于Web服务并不是一个真正可行的选择(我们使用它们中的一些),并且服务的API要求将记录存储在那里,因此遗憾地需要复制。

但我没有兴趣在我们的业务类中使用代码来处理每个方法,以便在数据更新时将数据同步到Web服务,而且我也不认为我的实体应该知道要更新自己的服务在一个属性设置器(或其他任何更新“真相”)。

我们使用NHibernate来满足所有DAL需求,在我看来,这个数据复制实际上是一个持久性问题 - 所以我使用EventListener(PostInsert和PostUpdate)来检查PoC实现,如果实体的类型为X,任何字段[Y..Z]都已更改,请使用新状态更新Web服务。

我觉得这在确保我们的数据是规范来源并确保透明地复制并最大限度地减少变更陷入崩溃的可能性并使我们陷入不匹配的情况之间取得了良好的平衡(不是世界末日,如果服务无法到达,我们稍后会进行手动批量更新,但是对于每个人在一般情况下的理智,目标是我们永远不必考虑它,但我的同事和我仍然有这种前进方式有一定程度的不舒服。

这是一个可怕的想法,会在不合时宜的时候邀请猛禽进入我的数据库吗?使用EventListener是完全合理的吗?对于一个不太理想的情况,它是一个可用的解决方案,我们可以直接使用并继续前进吗?如果我们沿着这条路走下去,那么在事件管道中我是否应该警惕任何陷阱?

1 个答案:

答案 0 :(得分:0)

如果数据存储不可靠(在您的情况下是Web服务),我将介绍事务(操作)的概念并将它们存储在本地数据库中,然后定期从数据库中提取它们并针对Web服务执行(其他数据存储) )。

这样的事情:

    public class OperationContainer
    {
    public Operation Operation; //what ever operations you need CRUD, or some specific
    public object Data; //your entity, business object or whatever
    }

    public class MyMailService
    {
    public SendMail (MailBusinessObject data)
    {
    DataAcceessLair<MailBusinessObject>.Persist(data);
    OperationContainer operation = new OperationContainer(){Operation=insert, Data=data};
    DataAcceessLair<OperationContainer>.Persist(operation);
    }
    }

    public class Updater
    {
    Timer EverySec;
    public void OnEverySec()
    {
    var data = DataAcceessLair<OperationContainer>.GetFirstIn(); //FIFO
    var webServiceData = WebServiceData.Converr(data); // do the logic to prepare data for WebService
try
{
    new WebService().DoSomething(data);
DataAcceessLair<OperationContainer>.Remove(data);
}
    }
    }

这实际上非常接近智能客户端的概念 - 技术上不是逻辑上的。看一下本书:使用C#进行.NET领域驱动设计:问题 - 设计 - 解决方案,第10章。或者看一下本书中的源代码,它非常接近您的情况:http://dddpds.codeplex.com/