城ウィンザー:どのように私は、コンポーネントの登録を更新することができます

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

と私は、この構成を拡張し、最終的な構成が効果的であるように、リスナーの配列プロパティに新しい項目を追加したい:

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

最初のコンポーネントを登録するとき、私は「アレイ」の内容を知っていなければならない、または私はコンポーネントの登録を取得し、それに追加することができますか?

私は、私は私のコンテナを構築して、異なるシナリオのために、必要に応じてそれを拡張することができるように、Decoratorパターンを使用して、私の設定を実装したいです。これは私がすでに設定されているコンポーネントにアクセスし、それらに追加できるようにする必要があることを意味します。

デフォルトの設定とデフォルトの設定を延長するより「DefaultConfig」クラス、のいずれかを返すクラスDecoratedConfigを有していると考えていた。

だから私は持っているでしょう。

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

(実施例に示されるように)DefaultConfigActivityServiceDefaultActivityListenerを設定することになる。

が作成されていたことDecoratedConfigを認識し、ActivityServiceListenersアレイに独自のリスナーの実装を追加しますActivityServiceます。

感謝します。

役に立ちましたか?

解決

Kernel.ComponentModelCreatedイベントを購読します。あなたはそこから任意のコンポーネントのパラメータを変更することができます。 こののを参照してください。それは、これを行う施設であることをのHAVE のない、それは便利です。

他のヒント

@mausch、ComponentModel構成をadustingはソリューションであることが表示されます。

以下の試験がeffecitvelyコンポーネントモデルが作成された後も、私は変更を加えることができるように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");
    }
}

IContributeComponentModelConstruction ComponentModel建設貢献をを使用することが好ましいです。それ以降のインタフェースは、さらにあなたのコンポーネントを設定する推奨される方法です。

これを実行するには、コンフィギュレーションに適用する変更を指定するためのインターフェイスを実装します。

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

すべてのコンポーネントは、あなたがそれらの設定を変更することができ、このクラスを通過します。あなたのケースなど、リスナーのリストをchangeingで

(私はこれはインターセプタの以前の名前だと思います)
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top