Windsor Container: как указать публичное свойство, которое не должно заполняться контейнером? - PullRequest
12 голосов
/ 07 октября 2008

При создании экземпляра класса Windsor по умолчанию обрабатывает все открытые свойства класса как необязательные зависимости и пытается их удовлетворить. В моем случае это создает довольно сложную циклическую зависимость, которая приводит к зависанию моего приложения.

Как я могу явно сказать Касл Виндзор, что он не должен пытаться удовлетворить государственную собственность? Я предполагаю, что должен быть атрибут в такой степени. Однако я не могу найти его, поэтому, пожалуйста, дайте мне знать соответствующее пространство имен / сборку.

Если есть какой-либо способ сделать это без атрибутов (таких как Конфигурация Xml или конфигурация с помощью кода), это было бы предпочтительным, поскольку конкретной библиотеке, где это происходит, до настоящего времени не требовалась зависимость от замка.

Ответы [ 7 ]

11 голосов
/ 08 октября 2008

Вы можете использовать атрибут Castle.Core.DoNotWireAttribute , чтобы предотвратить подключение свойства к контейнеру IoC (это в сборке Castle.Core, что означает, что вашей библиотеке нужно только взять зависимость от облегченной сборки Castle.Core - если, например, вы хотите использовать код без инверсии контейнера управления вообще или в другом контейнере IoC).

Я не верю, что есть какой-либо способ предотвратить возникновение проводки в конфигурации Xml, но было бы достаточно легко добавить поддержку для этого - если бы мне пришлось это сделать, я бы, вероятно,:

  1. Введите какой-то атрибут в объявлении свойства в xml:
  2. Наследовать от PropertiesDependenciesModelInspector , переопределяя метод InspectProperties , чтобы применять некоторую дополнительную логику для определения того, какие свойства должны быть добавлены в качестве зависимостей к модели компонентов (проверка модели. Конфигурация для проводника = "ложная" пара атрибут / значение).
  3. Унаследовать от DefaultComponentModelBuilder и переопределить InitializeContributors , чтобы включить замену PropertiesDependenciesModelInspector - или просто удалить существующий вкладчик свойств и добавить свой собственный во время выполнения через AddContributor / RemoveContributor методов.
  4. Замените ComponentModelBuilder экземпляр службы, назначенный для ядра вашего контейнера.

Другой подход, который может работать для вас, состоит в том, чтобы просто вручную удалить зависимости из модели, прежде чем запрашивать какие-либо экземпляры службы, т. Е.

kernel.GetHandler(typeof(MyComponent)).ComponentModel.Dependencies.RemoveAll(d => d.DependencyKey == "PropertyThatShouldNotBeWired");

YMMV с таким подходом - особенно если у вас есть запускаемые службы или другие средства, которые могут с нетерпением создавать экземпляр вашего компонента после его регистрации.

3 голосов
/ 01 сентября 2009

Я создал объект, чтобы помочь с этим:

2 голосов
/ 16 сентября 2013

Я не знаю, какую версию Castle вы, ребята, использовали в то время, но ни одно из упомянутых решений не работало. Плюс много мертвых ссылок.

С замком 3.1, вот решение, которое я придумал (благодаря копанию исходного кода замка):

container.Register(Component.For(type)
                                        .LifestyleTransient()
                                        .Properties( propertyInfo => propertyInfo.PropertyType != typeof(MyOtherType)));

Функция «Свойства» добавляет фильтр свойств, используемый Castle при создании ComponentModel. В моем случае будут удовлетворены все зависимости свойств, кроме типа свойства 'MyOtherType'.

1 голос
/ 12 февраля 2019

Это может быть достигнуто с помощью следующего кода:

var container = new WindsorContainer();

// We don't want to inject properties, only ctors
var propInjector = container.Kernel.ComponentModelBuilder
                         .Contributors
                         .OfType<PropertiesDependenciesModelInspector>()
                         .Single();
container.Kernel.ComponentModelBuilder.RemoveContributor(propInjector);

Источник Документация по замку Виндзор

1 голос
/ 21 ноября 2018

Может быть, это будет кому-то полезно. В Виндзоре 4.1 есть метод PropertiesIgnore при регистрации.

Component.For<Role>().LifestyleTransient().PropertiesIgnore((model, propertyInfo) => true)
0 голосов
/ 08 октября 2008

Разместил это на форуме групп Google здесь: http://groups.google.com/group/castle-project-devel/browse_thread/thread/43aa513817bd057a

...