Замок Виндзор:Как обновить регистрацию компонентов

StackOverflow https://stackoverflow.com/questions/938898

Вопрос

Если я определил в конфигурации:

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

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top