Windsor Container: как указать публичное свойство, которое не должно заполняться контейнером?
При создании экземпляра класса Windsor по умолчанию обрабатывает все открытые свойства класса как необязательные зависимости и пытается их удовлетворить. В моем случае это создает довольно сложную циклическую зависимость, которая приводит к зависанию моего приложения.
Как я могу явно сказать Касл Виндзор, что он не должен пытаться удовлетворить государственную собственность? Я предполагаю, что должен быть атрибут в такой степени. Однако я не могу найти его, поэтому, пожалуйста, дайте мне знать соответствующее пространство имен / сборку.
Если есть какой-либо способ сделать это без атрибутов (таких как Конфигурация Xml или конфигурация с помощью кода), это было бы предпочтительным, так как конкретная библиотека, где это происходит, до настоящего времени не нуждалась в зависимости от замка.
7 ответов
Я создал средство, чтобы помочь с этим:
Вы можете использовать атрибут Castle.Core.DoNotWireAttribute, чтобы остановить соединение свойства с контейнером IoC (это в сборке Castle.Core, что означает, что вашей библиотеке требуется только зависимость от облегченной сборки Castle.Core - например, если вы хотите использовать код без инверсии контейнера управления вообще или в другом контейнере IoC).
Я не верю, что есть какой-либо способ предотвратить возникновение проводки в конфигурации Xml, но было бы достаточно легко добавить поддержку для этого - если бы мне пришлось это сделать, я бы, вероятно,:
- Введите какой-то атрибут в объявление свойства в xml:
- Наследуйте от PropertiesDependenciesModelInspector, переопределяя метод InspectProperties, чтобы применить некоторую дополнительную логику для определения того, какие свойства должны быть добавлены в качестве зависимостей к модели компонентов (проверка model.Configuration для пары атрибут = значение wire="false").
- Унаследуйте от DefaultComponentModelBuilder и переопределите InitializeContributors, чтобы включить ваш замещающий PropertiesDependenciesModelInspector - или просто удалите существующий вкладчик свойств и добавьте свой собственный во время выполнения с помощью методов AddContributor/RemoveContributor.
- Замените экземпляр службы 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