Контейнер Windsor: как указать публичную собственность не следует заполнять контейнером?

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

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

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

Ответ 2

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

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

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

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

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

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

Ответ 3

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

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

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

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

Ответ 5

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

Component.For<Role>().LifestyleTransient().PropertiesIgnore((model, propertyInfo) => true)

Ответ 6

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

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);

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