C# 存储库有更改事件是一种代码气味吗?

C# 存储库有更改事件是一种代码气味吗?,c#,design-patterns,repository,C#,Design Patterns,Repository,我没有看到在存储库模式实现中使用更改事件,但我希望存储库如下所示: interface IEntityRepository { event EventHandler<EntityChangedEventArgs> EntityAdded; event EventHandler<EntityChangedEventArgs> EntityRemoved; IEnumerable<Entity> GetAll(); Entity

我没有看到在存储库模式实现中使用更改事件,但我希望存储库如下所示:

interface IEntityRepository
{
    event EventHandler<EntityChangedEventArgs> EntityAdded;
    event EventHandler<EntityChangedEventArgs> EntityRemoved;

    IEnumerable<Entity> GetAll();
    Entity GetById(int id);
}
interface-IEntityRepository
{
事件处理程序EntityAdded;
事件处理程序EntityRemoved;
IEnumerable GetAll();
实体GetById(int-id);
}
这在很大程度上是因为我的实体只能从外部添加和删除,而不能由IEntityRepository的客户机添加和删除


我这样做是对存储库模式的根本错误的思考,还是我有一个有效的案例?

如果您打算使用Fowler的实际存储库模式,我会说是的。该模式旨在通过公开类似于集合的接口来充当业务层和数据层之间的中介。它并不打算实际保存数据。也就是说,如果您只想创建一个集合来包装API并在事情发生变化时公开事件,那么一定要这样做。有时,您不需要遵循预定义的模式

如果你想让它成为一个模式,我会说它看起来更像一个对象池或观察者模式。请考虑使用<代码>可观察的< /代码>的情况。这将允许你对PInvoke层做出反应,并迫使你的责任落到实处。代码实际上比事件更有效。通过使用事件,您必须维护这个存储库,跟踪对象的生命周期,可能使这个存储库成为一个单独的存储库,并给它一些线程管理。使用Rx,您只需在观察者队列上推送一个操作


但最后,使用你觉得最自然的东西。模式只是建议,并不总是存在于每个潜在的用例中。这就是其中之一。

我有一个类似的问题,我需要将事件发布到事件存储中,以便对数据库执行CUD操作(不关心读取操作)。我没有修改我的回购协议,而是创建了一个装饰器并注入它(使用)。这满足了开放/封闭原则和单一责任,实际上它提供了一种更干净的方法来处理该要求。

Meh。模式不是福音。你认为这样做会产生什么样的问题?显而易见的问题是,如果
IEntityRepository
不负责修改实体,它怎么知道实体是否发生了变化?@Ritch:我认为没有功能问题,但可能是沟通问题;如果事件被暴露,它甚至可以按照存储库模式被称为存储库吗?@driushkin:repository实现是本机代码上的P/Invoke包装器,当网络IO通知网络另一端发生了新的或删除的实体时,它会发出回调。@Johann Gerell-FIIK,但是您可以拆分接口并将正确的版本传递给相应的调用方吗?我倾向于使用组合接口。