Замок Виндзор: Как я могу обновить регистрацию компонентов - PullRequest
3 голосов
/ 02 июня 2009

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

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.

Спасибо.

Ответы [ 3 ]

2 голосов
/ 02 июня 2009

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

0 голосов
/ 23 июля 2014

Предпочтительно использовать конструкторы 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());

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

0 голосов
/ 03 июня 2009

@ 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");
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...