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

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

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

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

7 ответов

Решение

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

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

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

  1. Введите какой-то атрибут в объявление свойства в xml:
  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 с таким подходом - особенно, если у вас есть запускаемые службы или другие средства, которые могут с радостью создавать экземпляр вашего компонента после его регистрации.

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

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

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

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

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

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

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

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

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

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

Другие вопросы по тегам