Замок Виндзор:Как обновить регистрацию компонентов
-
06-09-2019 - |
Вопрос
Если я определил в конфигурации:
container.Register(
Component.For<X.Y.Z.IActivityService>()
.ImplementedBy<X.Y.Z.ActivityService>()
.ServiceOverrides(ServiceOverride.ForKey("Listeners").Eq(new [] { typeof(X.Y.Z.DefaultActivityListener).FullName }))
.LifeStyle.Transient
);
и я хочу расширить эту конфигурацию и добавить новый элемент в свойство массива Listeners, чтобы окончательная конфигурация была эффективной:
container.Register(
Component.For<X.Y.Z.IActivityService>()
.ImplementedBy<X.Y.Z.ActivityService>()
.ServiceOverrides(ServiceOverride.ForKey("Listeners").Eq(new [] { typeof(X.Y.Z.DefaultActivityListener).FullName, "MyOtherListenerID" }))
.LifeStyle.Transient
);
должен ли я знать содержимое «массива» при первой регистрации компонента или я могу получить регистрацию компонента и добавить к ней?
Я хочу реализовать свою конфигурацию с использованием шаблона декоратора, чтобы я мог построить свой контейнер, а затем расширить его по мере необходимости для различных сценариев.Это означает, что мне нужно иметь доступ к уже настроенным компонентам и добавлять к ним элементы.
Думал о проведении урока DefaultConfig
которые возвращают настройку по умолчанию, а затем одну или несколько "DecoratedConfig
"классы, которые расширят конфигурацию по умолчанию.
Так что я бы имел
IWindsorContaner c = new DecoratedConfig(new DefaultConfig()).InitialiseContainer();
DefaultConfig
бы создать ActivityService
с DefaultActivityListener
(как показано в примере).
DecoratedConfig
признал бы это ActivityService
был создан и добавил свою собственную реализацию Listener в Listeners
массив включен ActivityService
.
Спасибо.
Решение
Подпишитесь на Kernel.ComponentModelCreated
событие.Отсюда вы можете изменить любой параметр компонента.Видеть этот.Это не так иметь быть учреждением, которое это делает, но это удобно.
Другие советы
@mausch, настраиваю ComponentModel
Конфигурация, по-видимому, является решением.
Приведенный ниже тест эффективно выполняет то, что мне нужно, без необходимости подключения к ComponentModelCreatedEvent
поэтому я могу вносить изменения даже после создания модели компонента.
Я оберну эту функциональность как метод расширения и попытаюсь адаптировать ее к гибкому API.
[TestMethod]
public void ArrayPropertyTestApi3()
{
using (Castle.Windsor.WindsorContainer container = new Castle.Windsor.WindsorContainer())
{
container.Register(Component.For<Components.A>().ServiceOverrides(ServiceOverride.ForKey("I").Eq(new[] { typeof(Components.B).FullName })));
container.Register(Component.For<Components.B>());
container.Register(Component.For<Components.C>());
IHandler h = container.Kernel.GetHandler(typeof(Components.A));
if (h != null)
{
var config = h.ComponentModel.Configuration;
if (config != null)
{
var items = config.Children.Single(c => c.Name == "parameters")
.Children.Single(c => c.Name == "I")
.Children.Single(c => c.Name == "list")
as MutableConfiguration;
items.Children.Add(new MutableConfiguration("item", string.Format("${{{0}}}", typeof(Components.C).FullName)));
}
}
Components.A svc = container.Resolve<Components.A>();
Assert.IsTrue(svc.I.Length == 2);
Assert.IsTrue(svc.I[0].Name == "B");
Assert.IsTrue(svc.I[1].Name == "C");
}
}
Предпочтительно использовать Участники построения ComponentModel с IContributeComponentModelConstruction
интерфейс, поскольку это рекомендуемый способ дальнейшей настройки ваших компонентов.
Для этого вы должны реализовать интерфейс, чтобы указать изменения, которые следует применить к конфигурации.
public class ChangeConfiguration : IContributeComponentModelConstruction
{
public void ProcessModel(IKernel kernel, ComponentModel model)
{
// filter your model to match the subset you're interested in
// change the configuration for matching models
}
}
Затем перед регистрацией компонентов вы просто добавляете класс в свой контейнер:
container.Kernel.ComponentModelBuilder.AddContributor(new ChangeConfiguration());
Все компоненты затем пройдут через этот класс, где вы сможете изменить их конфигурацию.В вашем случае изменение списка прослушивателей и т. д. (думаю, это предыдущее название перехватчиков)