基于供应商配置 Windsor 容器时出现问题

发布于 2024-09-30 01:15:58 字数 1999 浏览 1 评论 0原文

我对 IoC/DI 的整个概念相当熟悉,但我以前从未实现过解决方案。这是我第一次,所以如果您认为有必要,请随时给我正确的方向推动。

我有多个类实现相同的接口(IMyCustomFileReader)。我需要根据应用程序中的一些供应商信息使用这些实例之一。如果供应商是 Vendor1,我希望 IoC 容器在请求 IMyCustomFileReader 实例时为我提供 Vendor1FlatFileReaderDummyClass1分别是 IDummyInterface

同样,当供应商为 Vendor2 时,我希望容器返回 XMLFileReaderDummyClass2 的实例。

我认为(如果我错了请告诉我)我可以使用ChildContainers来使用它。目前我的 xml 如下所示:

<components>
  <component id="Vendor1"
             service="SomeAssembly.IMyCustomFileReader, SomeAssembly"
             type="SomeAssembly.Vendor1.Vendor1FlatFileReader, SomeAssembly.Vendor1">
  </component>
  <component id="Vendor1"
             service="SomeAssembly.IDummyInterface, SomeAssembly"
             type="SomeAssembly.DummyClass1, SomeAssembly">
  </component>

  <component id="Vendor2"
             service="SomeAssembly.IMyCustomFileReader, SomeAssembly"
             type="SomeAssembly.XMLFileReader, SomeAssembly">
  </component>
  <component id="Vendor2"
             service="SomeAssembly.IDummyInterface, SomeAssembly"
             type="SomeAssembly.DummyClass2, SomeAssembly">
  </component>
</components>

此配置是错误的,因为我不能拥有具有相同 id 元素的多个组件 - 即使接口不同(如上面的示例所示)也是如此。我希望我可以做类似 Container.Resolve("Vendor1") 的事情,然后当请求 IMyCustomFileReader 实例并且 key 时code> 值是 Vendor1 我会返回 Vendor1FlatFileReader 的实例。

当我尝试这样做时,出现 Castle.MicroKernel.ComponentRegistrationException

我认为可能有用的其他东西是 ChildContainers 的概念,但是我将如何在 xml 中配置它们呢?

另外,我不想给我的组件命名,例如 Vendor1_IMyCustomFileReaderVendor2_IMyCustomFileReader。我还希望只有 1 个配置文件,而不是为每个供应商提供单独的配置文件(如果可能)。以前有其他人遇到过类似的问题吗?我该如何解决这个问题?

I'm fairly familiar with the whole concept of IoC/DI, but I've never implemented a solution before. This is my first time, so please feel free to give me a push in the right direction if you deem it necessary.

I've got multiple classes that implement the same Interface(IMyCustomFileReader). I need to use one of these instances based on some Vendor information in my application. If the Vendor is Vendor1 I would like the IoC container to give me Vendor1FlatFileReader and DummyClass1 when I request an instance of IMyCustomFileReader and IDummyInterface respectively.

Similarly I would like the container to return instances of XMLFileReader and DummyClass2 when the Vendor is Vendor2.

I think (and let me know when I'm wrong) that I can use it using ChildContainers. At the moment my xml looks like this:

<components>
  <component id="Vendor1"
             service="SomeAssembly.IMyCustomFileReader, SomeAssembly"
             type="SomeAssembly.Vendor1.Vendor1FlatFileReader, SomeAssembly.Vendor1">
  </component>
  <component id="Vendor1"
             service="SomeAssembly.IDummyInterface, SomeAssembly"
             type="SomeAssembly.DummyClass1, SomeAssembly">
  </component>

  <component id="Vendor2"
             service="SomeAssembly.IMyCustomFileReader, SomeAssembly"
             type="SomeAssembly.XMLFileReader, SomeAssembly">
  </component>
  <component id="Vendor2"
             service="SomeAssembly.IDummyInterface, SomeAssembly"
             type="SomeAssembly.DummyClass2, SomeAssembly">
  </component>
</components>

This configuration is erroneous as I cannot have multiple components with the same id element - Not even when the Interfaces are different like in the above example. I was hoping I could do something like Container.Resolve<IMyCustomFileReader>("Vendor1"), then when an instance of IMyCustomFileReader is requested and the key value is Vendor1 I would get back an instance of Vendor1FlatFileReader.

I get a Castle.MicroKernel.ComponentRegistrationException when I try to do it this way.

Something else I think might work is the concept of ChildContainers, but how would I go about configuring those in xml?

Also, I would prefer not to give my components names like Vendor1_IMyCustomFileReader and Vendor2_IMyCustomFileReader. I would also prefer to have only 1 configuration file and not separate ones for each Vendor (if possible). Has anyone else encountered a similar problem before? How can I solve this?

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

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

发布评论

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

评论(2

北方的韩爷 2024-10-07 01:15:58

是的,组件 ID 必须是唯一的。我不会推荐子容器,除非你真的知道你在做什么。在这种情况下,您似乎正在尝试进行某种多租户,因此我建议您查看 处理程序选择器,这将允许您根据“供应商”选择适当的组件,而无需求助于服务位置(如果您在应用程序级代码中执行container.Resolve(),您已经丢失了)。

Yes, component ids must be unique. I wouldn't recommend child containers unless you really know what you're doing. In this case, it looks like you're trying to do some sort of multi-tenancy, so I recommend taking a look at handler selectors, this will let you select the appropriate component based on the "vendor" without resorting to service location (if you do container.Resolve() in application-level code, you already lost).

柠檬心 2024-10-07 01:15:58

您愿意使用Fluent 注册 API 吗?如果是这样,您可以根据“供应商”决定在运行时注册哪些组件(每个供应商的注册可以位于单独的 IWindsorInstaller 实现)。该解决方案假设您知道在启动时使用哪个“供应商”,并且“供应商”在应用程序的整个生命周期中不会改变(我猜测这是基于您如何陈述问题的有效假设)。您可以对 XML 配置采取类似的方法,但是您需要将每个供应商的配置分离到单独的配置文件中,并且您说您反对这样做 - 您能解释一下原因吗?

如果您认为 Fluent API 方法可行,请发表评论并告诉我,我很乐意发布一个示例。

Would you be willing to use the fluent registration API? If so, you could decide which components to register at runtime based on the "vendor" (the registrations for each vendor could live in a separate IWindsorInstaller implementation). This solution assumes you know which "vendor" to use at start-up and that the "vendor" will not change throughout the lifetime of the application (I'm guessing that is a valid assumption based on how you stated the question). You could take a similar approach with XML configuration, but you would need to separate the configuration for each vendor into separate config files, and you say you are opposed to that -- could you clarify why?

Please comment and let me know if you think that the fluent API approach could work, and I'd be happy to post an example.

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