Проблема с настройкой контейнера Windsor на основе Vendor - PullRequest
0 голосов
/ 02 ноября 2010

Я довольно знаком со всей концепцией IoC / DI, но я никогда не реализовывал решение раньше.Это мой первый раз, поэтому, пожалуйста, не стесняйтесь дать мне толчок в правильном направлении, если вы сочтете это необходимым.

У меня есть несколько классов, реализующих один и тот же интерфейс (IMyCustomFileReader).Мне нужно использовать один из этих экземпляров на основе некоторой информации Vendor в моем приложении.Если Vendor - Vendor1 , я бы хотел, чтобы контейнер IoC выдал мне Vendor1FlatFileReader и DummyClass1, когда я запрашиваю экземпляры IMyCustomFileReader и IDummyInterface соответственно.

Аналогично яхотел бы, чтобы контейнер возвращал экземпляры XMLFileReader и DummyClass2, когда Vendor равен Vendor2 .

Я думаю (и сообщаю, когда я ошибаюсь), что я могу использоватьэто используя 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<IMyCustomFileReader>("Vendor1"), тогда, когда будет запрошен экземпляр IMyCustomFileReader, а значение key равно Vendor1 , я получу обратно экземпляр Vendor1FlatFileReader.

Я получаю Castle.MicroKernel.ComponentRegistrationException, когда пытаюсь сделать это таким образом.

Что-то еще, что я думаю, может сработать, это концепция ChildContainers, но как мне настроить их в xml?

Кроме того, я бы предпочел не давать именам компонентов, таким как Vendor1_IMyCustomFileReader и Vendor2_IMyCustomFileReader.Я также предпочел бы иметь только 1 файл конфигурации, а не отдельные файлы для каждого поставщика (если это возможно).Кто-нибудь еще сталкивался с подобной проблемой раньше?Как я могу решить это?

Ответы [ 2 ]

1 голос
/ 02 ноября 2010

Да, идентификаторы компонентов должны быть уникальными.Я бы не рекомендовал дочерние контейнеры, если вы действительно не знаете, что делаете.В этом случае, похоже, что вы пытаетесь сделать какую-то мультитенантность, поэтому я рекомендую взглянуть на селектор обработчиков , это позволит вам выбрать соответствующий компонент на основе «поставщика»без обращения к расположению службы (если вы выполняете container.Resolve () в коде уровня приложения, вы уже потеряли).

0 голосов
/ 02 ноября 2010

Желаете ли вы использовать свободный API регистрации ?Если это так, вы можете решить, какие компоненты регистрировать во время выполнения, основываясь на «вендоре» (регистрации для каждого вендора могут находиться в отдельной реализации IWindsorInstaller ).Это решение предполагает, что вы знаете, какого «поставщика» использовать при запуске, и что «поставщик» не будет меняться в течение всего срока службы приложения (я полагаю, что это правильное предположение, основанное на том, как вы сформулировали вопрос).Вы можете использовать аналогичный подход с конфигурацией XML, но вам нужно будет разделить конфигурацию для каждого поставщика на отдельные файлы конфигурации, и вы скажете, что вы против этого - не могли бы вы уточнить, почему?дайте мне знать, если вы считаете, что свободный подход API может работать, и я был бы рад опубликовать пример.

...