3

私のアプリは、基本的なパブリッシュ/サブスクライブ通知モデル ( http://caliburn.codeplex.com/wikipage?title=The%20Event%20Aggregator )である複数のイベント バス オブジェクトに依存しています。

私がやりたいことは、アグリゲーターの特定のインスタンスをコンポーネントのグループと共有することです。コンポーネント A、B、C の間で共有される 1 つのイベント バスと、D、E、F の間で共有される別のイベント バスがあるとします。

基本的に、イベントバスをシングルトンとして宣言し、いくつかの基準に基づいて注入したいと考えています。解像度を区別するためだけに、イベント バスのサブタイプを作成することは避けたいと思います。

パラメータのメタデータ解決を可能にする Java で Google Guice IoC を使用しました。別名Javaでは、これと同等のことができました。

例:

public A([SpecialUseAggregator]IEventAggregator something)
public B([SpecialUseAggregator]IEventAggregator something)

public E([AnotherUseAggregator]IEventAggregator something)
public F([AnotherUseAggregator]IEventAggregator something)

助言がありますか?

4

1 に答える 1

5

Autofac には、登録用の属性がありません/使用されません。解決策の 1 つは、 Named/Keyed登録機能を使用することです。

したがって、異なる名前/キーで2つを登録する必要がありEventAggreator、コンシューマタイプA、Bなどを登録するときに、を使用して、特定のインスタンスにどちらを使用する必要があるかをWithParameterAutofacに伝えることができます:IEventAggreator

var contianerBuilder = new ContainerBuilder();
contianerBuilder.Register(c => CreateAndConfigureSpecialEventAggregator())
                        .Named<IEventAggreator>("SpecialUseAggregator");
contianerBuilder.Register(c => CreateAndConfigureAnotherUseAggregator())
                        .Named<IEventAggreator>("AnotherUseAggregator");

contianerBuilder.RegisterType<A>).AsSelf()
                 .WithParameter(ResolvedParameter
                 .ForNamed<IEventAggreator>("SpecialUseAggregator"));
contianerBuilder.RegisterType<B>().AsSelf()
                 .WithParameter(ResolvedParameter
                 .ForNamed<IEventAggreator>("SpecialUseAggregator"));
contianerBuilder.RegisterType<C>).AsSelf()
                 .WithParameter(ResolvedParameter
                 .ForNamed<IEventAggreator>("AnotherUseAggregator"));
contianerBuilder.RegisterType<D>().AsSelf()
                 .WithParameter(ResolvedParameter
                 .ForNamed<IEventAggreator>("AnotherUseAggregator"));
var container = contianerBuilder.Build();

属性を使用したい場合は、Autofac でそれを行うことができます。必要な拡張ポイントがすべて含まれているため、属性について Autofac に教えて正しく使用するためのコードがさらに必要なだけです。

WithParameterタイプをスキャンで登録している場合、登録を簡単に使用することはできませんが、Autofacのメタデータ機能を使用します。

EventAggreator キーを保持する属性を作成するだけです。

public class EventAggrAttribute : Attribute
{
    public string Key { get; set; }

    public EventAggrAttribute(string key)
    {
        Key = key;
    }
}

そしてあなたのクラスを属性:

[EventAggrAttribute("SpecialUseAggregator")]
public class AViewModel
{
    public AViewModel(IEventAggreator eventAggreator)
    {
    }
}

次に、スキャンを実行するときに、 を使用しWithMetadataFromてメタデータを登録する必要があります。

contianerBuilder.RegisterAssemblyTypes(Assembly.GetExecutingAssembly())
            .Where(t => t.Name.EndsWith("ViewModel"))
            .OnPreparing(Method)
            .WithMetadataFrom<EventAggrAttribute>();

最後にOnPreparing、メタデータ ベースの解決を行うイベントが必要です。

private void Method(PreparingEventArgs obj)
{
    // Metadata["Key"] is coming from the EventAggrAttribute.Key
    var key = obj.Component.Metadata["Key"].ToString();
    ResolvedParameter resolvedParameter = 
        ResolvedParameter.ForNamed<IEventAggreator>();
    obj.Parameters = new List<Parameter>() { resolvedParameter};
}

これが作業単体テストの要点です。

于 2013-04-24T04:53:45.567 に答える