我们有两个独立的现有应用程序,只能通过总线消息系统和数据库进行通信。现在我们想要通知第二个应用程序有关在db update之前或之后在第一个应用程序中对我们的域模型所做的任何更改:一旦我们知道存储器中存储了真正的更改或刚刚保存,我们就想发送特定的消息单独的申请。消息不表示进行了哪种更改。
一些注意事项:
您建议我们在应用程序设计方面使用哪些方法?数据层通过总线系统提交此类通知是否良好?我们怎么知道数据实际发生了变化:我们可以通过NHiberate会话知道它还是我们跟踪域模型中的变化?
答案 0 :(得分:2)
数据层通过总线系统提交此类通知是否良好?
不,不是。虽然有些框架支持开箱即用,但自己拥有或写入通常是错误的。这里的问题有两个 -
我们怎么知道数据实际发生了变化:我们可以通过NHiberate会话知道它还是我们跟踪域模型中的变化?
您对要求和此问题的陈述存在一些不一致之处。你这样表达了它 - "如果消息发送的时间早于将数据提交给数据库,即使它们最终被拒绝了,也没关系#34; 然后你说它与知道相关数据实际上已经改变了。
无论如何,如果将数据直接保存到DB,它通常会返回一些指示,例如修改的行数。当使用像NHibernate这样的ORM框架时,您通常可以立即提交事务并获得相同的指示。
在这两种方式中,只有当数据在数据库中实际更改时,如果另一个应用程序从同一个数据库中检索数据,您应该让其他应用程序知道。
您建议我们在应用程序设计方面使用哪种方法?
我们通过将事件作为逻辑过程的一部分发布而不是作为持久性的一部分来解决此问题,因为您可能有一些不需要通知的操作。如果您仍然希望在数据方面这样做,我建议不要在您的存储库中对其进行硬编码,而是使用Martin fowler的Unit of work或Transaction script模式。它们将允许您决定哪些数据事务应该发布事件,哪些不是,以及何时发布。
答案 1 :(得分:1)
数据层通过以下方式提交此类通知是否良好? 公交系统?
不,但是如果您需要为每次更改提出这样的通知,并且如果您可以将这些事件绑定到系统的管道中而不需要更改所有存储库,那就OK了。
我们怎么知道数据实际发生了变化:我们可以通过NHiberate会话知道它还是我们必须跟踪域内的变化 模型?
此问题的最简单解决方案是使用interceptor or an event。 这样的事情可以解决你的问题,
活动
(请参阅this获取完整示例)
public class ChangeEventListener : IFlushEntityEventListener
{
public SetModificationTimeFlushEntityEventListener()
{
CurrentDateTimeProvider = () => DateTime.Now;
}
public void OnFlushEntity(FlushEntityEvent @event)
{
var entity = @event.Entity;
var entityEntry = @event.EntityEntry;
if (entityEntry.Status == Status.Deleted)
{
//raise event
}
var trackable = entity as ITrackModificationDate;
if (trackable == null)
{
return;
}
if (HasDirtyProperties(@event))
{
//raise event
}
}
}
<强>拦截强>
public class NotificationInterceptor : EmptyInterceptor
{
public override bool OnFlushDirty(object entity,
object id,
object[] currentState,
object[] previousState,
string[] propertyNames,
IType[] types)
{
//do check for changed states by comparing current and previous values, and raise event if changed
return true
}
}