Pergunta

Se eu tiver definido em config:

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

e gostaria de estender essa configuração e adicionar um novo item para a propriedade de matriz Ouvintes de tal forma que a configuração final é efetivamente:

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

deve Eu sei o conteúdo do "array" quando o primeiro registrar o componente, ou eu posso recuperar o registro do componente e adicionar a ele?

Eu gostaria de implementar minha configuração usando o padrão decorador tal que eu posso construir a minha recipiente, e, em seguida, estendê-lo conforme necessário para diferentes cenários. Isso significa que eu preciso ser capaz de acessar os componentes já configuradas e adicionar a eles.

Foi pensando em ter um DefaultConfig classe que retornar a configuração padrão e, em seguida, um dos mais classes "DecoratedConfig", que se estenderia a configuração padrão.

Então, eu teria

IWindsorContaner c = new DecoratedConfig(new DefaultConfig()).InitialiseContainer();

DefaultConfig iria configurar o ActivityService com um DefaultActivityListener (como mostrado no exemplo).

DecoratedConfig reconheceria que ActivityService tinha sido criado e adicionar sua própria implementação Listener para a matriz Listeners em ActivityService.

Graças.

Foi útil?

Solução

Inscrever-se para o evento Kernel.ComponentModelCreated. Você pode alterar qualquer parâmetro componente de lá. Consulte este . Não faz Have para ser uma instalação que faz isso, mas é conveniente.

Outras dicas

@mausch, adusting a configuração ComponentModel parece ser a solução.

A seguir teste effecitvely faz o que eu preciso sem ter que ligar para o ComponentModelCreatedEvent para que eu possa fazer as mudanças, mesmo depois de o modelo de componente é criado.

Vou quebrar a funcionalidade como um método de extensão, e tentar ajuste a uma API fluente.

[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");
    }
}

É preferível usar os ComponentModel construção contribuidores com o IContributeComponentModelConstruction Interface, uma vez que é a maneira recomendada de configurar os componentes mais.

Para fazer isso, você poderia implementar a interface para especificar que as alterações se aplicam a configuração

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
    }
}

Em seguida, antes de registrar seus componentes, você acabou de adicionar a classe ao seu recipiente:

container.Kernel.ComponentModelBuilder.AddContributor(new ChangeConfiguration());

Todos os componentes, então, passar por esta classe, onde você pode alterar sua configuração. No seu caso changeing a lista ouvinte, etc (eu acho que este é o nome anterior dos interceptores)

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top