MVVM 交替事件模式

发布于 2024-11-28 21:32:26 字数 611 浏览 0 评论 0原文

我目前有一个看起来像这样的层次结构

MainWindowViewModel
    TabViewModel
        EditorViewModel
            ReviewingServices
                ConflictFinder

我遇到的问题是 TabViewModel 希望收到冲突通知(来自 ReviewingServices)以及其他事情。我可以为所有依赖项创建公共 getter,并使用 DependencyA.DependencyB.DependencyC += SomeHandler; 订阅我想要的任何内容,但这相当混乱。我发现自己创造了太多我想数的事件。本质上,我创建了一个混乱的事件网。我喜欢为每个班级创建的职责分离,但当每个班级都有 2-3 个活动时,维护起来相当困难。如果订阅者仅比上面 1 级,我在创建和维护事件时没有问题。当说 MainWindowViewModel 希望收到新评论的通知(从 ReviewingServies 发布)时,就会出现混乱。

在订阅者想要订阅的情况下,是否有更好的方法来处理这些类型的事件深度嵌套在应用程序中的事件?

I currently have a hierarchy that looks like this

MainWindowViewModel
    TabViewModel
        EditorViewModel
            ReviewingServices
                ConflictFinder

The issue I'm running into is that TabViewModel wants to be notified of conflicts (from ReviewingServices) as well as other things. I could create public getters for all my dependencies and subscribe to whatever I want with DependencyA.DependencyB.DependencyC += SomeHandler; but that's rather messy. I'm finding myself creating far too many events that I wish to count. Essentially, I've created a messy web of events. I love the separation of responsibilities that I've created for every class but when every class has 2-3 events each it's rather difficult to maintain. I'm having no issues creating and maintaining events if the subscriber is only 1 level above. The mess comes when say MainWindowViewModel wishes to be notified of new reviews (published from ReviewingServies.

Is there a better of doing these types of events where a subscriber could want to subscribe to events that are deeply nested in the application?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

又爬满兰若 2024-12-05 21:32:26

我不知道我是否真的遇到了你的麻烦,但我建议看看某种事件聚合器。尝试查看 Caliburn one,但与您自己实现一个并没有太大不同。这样,您就可以用类型命名事件并从任何地方订阅它。

I don't know if I really got your trouble, but I suggest to look at some kind of event aggregator. Try to check out the Caliburn one, but is not so different to implement one yourself. With this you name the event with a type and subscribe to it from everywhere.

像你 2024-12-05 21:32:26

尝试使用 Microsoft Prism 及其事件聚合器

Try using Microsoft Prism and their Event Aggregator

想念有你 2024-12-05 21:32:26

链接 DependencyA.DependencyB.DependencyC 通常被认为违反了德米特定律 (您实际上依赖于依赖项的依赖项,等等)。

我最近通过使用由诸如 IMyOperationNameContext 之类的接口定义的 Mediator 解决了类似的设计问题 这允许我将两个 ViewModel 的组合上下文与 WinForms 控件共享/注入到 WinForms 控件中,该控件使用第三个 ViewModel 以及所有这些,而无需将三个模型直接耦合在一起。

像这样的东西(注意示例中的 IAlbumContext 如何更多地充当代理,但这只是因为示例被简化了):

interface IAlbumContext
{
    public AlbumInfo SelectedAlbum { get; set; }
}

class AlbumContext
{
    AlbumSelectionViewModel _model;

    public AlbumContext(AlbumSelectionViewModel model)
    {
        _model = model;
    }     

    public Album SelectedAlbum {
        get { return _model.Album; }
    }
}

class PhotoUploadDialog : Dialog
{
    public PhotoUploadDialog(IAlbumContext context, PhotoUploadViewModel viewModel)
    {
    }
}

虽然这个解决方案对我有用,而且我喜欢它具有高内聚性和解耦性它最终无法大规模扩展(例如,此类上下文接口的数量可能会根据应用程序而快速增长)。然而,对于更通用的解决方案,代价是代码变得更难遵循。

Chaining DependencyA.DependencyB.DependencyC is generally considered breaking the Law of Demeter (you are effectively relying on a dependency of a dependency, etc).

I recently solved a similar design problem by using a Mediator defined by an interface such as IMyOperationNameContext which allowed me to share/inject the combined context of two ViewModels with/into a WinForms control which uses a third ViewModel and all of that without coupling the three models together directly.

Something like this (note how in the sample the IAlbumContext acts more as a proxy, but that's just because the sample is simplified):

interface IAlbumContext
{
    public AlbumInfo SelectedAlbum { get; set; }
}

class AlbumContext
{
    AlbumSelectionViewModel _model;

    public AlbumContext(AlbumSelectionViewModel model)
    {
        _model = model;
    }     

    public Album SelectedAlbum {
        get { return _model.Album; }
    }
}

class PhotoUploadDialog : Dialog
{
    public PhotoUploadDialog(IAlbumContext context, PhotoUploadViewModel viewModel)
    {
    }
}

While this solution worked for me and I like that it's with high cohesion and decoupled it's ultimately not massively scalable (e.g the number of such context interfaces can grow rapidly depending on the app). However with a more generic solution the trade-off is that the code gets harder to follow.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文