代码之家  ›  专栏  ›  技术社区  ›  Nicolas

c#/中多个Rx受试者的依赖注入。净核心

  •  0
  • Nicolas  · 技术社区  · 7 年前

    我在a中有以下场景。net core C#应用程序:

    Service A -> Subject<Foo> -> Service B Service C -> Subject<Foo> -> Service D

    的两个实例 Subject<Foo> 具有不同的语义,因此它们需要是不同的实例。让我们假设第一个主题是“棒极了” Foo s、 第二个是“很棒” Foo公司 s

    服务A依赖于 主题(<Foo> 以及服务B。 现在,我想使用dotnet core附带的依赖项注入来添加 主题(<Foo> 至容器 因此,所有服务都可以用它们所依赖的主题构建(A和B依赖于第一个实例,C和D依赖于第二个实例)。

    我的第一个想法是创建派生接口 IFooFirstSubject : ISubject<Foo> IFooSecondSubject : ISubject<Foo> :

    services.AddSingleton<IFooFirstSubject>( HOW TO GET A FooFirstSubject Instance?! ); services.AddSingleton<IFooSecondSubject>( HOW TO GET A FooSecondSubject Instance?! );

    然而,现在我需要一个具体的主题实现来实现 IFooFirstSubject 界面一个想法是将 Subject 并实现标记接口,但 主题 是一个密封类。我目前看到三种方法,但我对其中任何一种都不满意:

    1) 而不是根据主题制作A和B, 创建 SubjectRegister 具体类,从中A、B、C、D可以查询他们想要的主题 subjectRegister.FooFirstSubject . 把收银机放在两者之间对我来说就像一股气味。

    2) 使用适配器模式 解决密封类问题。 FooFirstSubject 然后可以实施 IFooFirstSubject 并使用(非派生自)a 主题 . 如果我在两个部门之间有很多科目的话,那似乎需要做很多工作。

    3) 可能有一种方法可以添加标记接口 使用反射。 这也让我觉得我在做一些不该做的事情。

    本质上: 还有别的方法吗(也许我用错了 主题 在这里?)为了实现我的目标?

    编辑: 我对 为什么? 什么 我想在这里完成(由于有很多评论,谢谢他们!): https://gist.github.com/anonymous/e933846c2c8e213128a49a2a6f8f7154

    2 回复  |  直到 7 年前
        1
  •  2
  •   poke    7 年前

    问题是,依赖注入可以 类型 如果有两个完全相同类型的实例,那么DI无法消除这两个实例之间的歧义。至少,除非您使用Microsoft中不可用的键控依赖项。扩展。依赖注入和 which could be a sign for a bad design .

    你应该考虑一下你是否真的需要单独的科目。我理解你的情况的方式(以及更具体的基于推特的例子)是,你使用这个主题来发布关于这个问题的事件 Foo 对象您需要两个不同的主题,因为您有两个不同的事件,需要不同的组件订阅。

    所以你实际上 不同的事件类型 ,这意味着,与其让主题与事件相关 目标 ,你应该有关于 事件 相反所以你会有 Subject<AwesomeFooDelivered> 和a Subject<GreatFooDelivered> . 然后,这两个事件都将引用实际 Foo公司 但这样组件就可以订阅实际事件,而不是 某物 发生在它身上。

    以你的问答问题为例,这将使 Subject<QuestionPosted> Subject<QuestionUpvoted> ; 以你的推文为例 Subject<TweetReceived> Subject<HashtagDiscovered> .

    通过在事件上设置主题,您可以轻松地让多个组件订阅同一事件主题,并让多个组件独立订阅事件。因此,这将允许真正的解耦。

    由于主题现在属于不同的类型,您也不会有问题将其注册为依赖项,依赖于它们的组件将再次清楚地了解它们实际依赖的内容,从而使您的体系结构更加清晰。

        2
  •  2
  •   McGuireV10    7 年前

    只需注册具体实现的一个实例。 接口良好,但并非严格必要。

    services.AddSingleton(new Subject<Foo>());