2011-02-10 14 views
2

はすべて登録されたサービスを取得するために次の操作を行うことができます。名前や鍵で登録されていても、Autofacではあるタイプのすべてのサービスを解決できますか? Autofac一

IEnumerable<MyClass> all = Context.Resolve<IEnumerable<MyClass>>() 

しかし、これは名前のサービスとして登録されたものが含まれていません。

Autofacソースを見ると、これはTypedServiceまたはKeyedServiceのどちらかに基づいてサービスがクエリされるためです。

名前に登録されているかどうかにかかわらず、すべてのサービスをIEnumerableに解決する方法はありますか?

答えて

5

builder.Register<CupOfT>() 
    .As<IBeverage>() 
    .Keyed<IBeverage>("someKey"); 

あなたはその後、ちょうどあなたが後にしている結果を得るためにIEnumerable<IBeverage>を解決することができますが、キー(または名前)で解決することもできます。

IBeverageの特定のデフォルト登録を維持することを心配している場合は、他のものにPreseveExistingDefaults()を使用してください(または、意図したデフォルトが最後に登録されていることを確認してください)。

HTH!

ニック

+0

OPからの応答が遅れた後のクイックヘルプはあまり禅ではありません。私は私の質問で、必ずしもすべての登録を管理しているとは言えませんでした。これは、サイトを構築するためのフレームワーク(Umbraco 5)の中で、Autofacの上にある抽象化の一部です。我々のフレームワークは、他のコンテナや他のリリースのAutofacにビジネスやその他の依存関係を持つサードパーティのソリューションでも使用できます。プロバイダ固有の内部登録コード。 –

1

私は動作していると思われる方法を書いています。 Autofacでこれを行う組み込みの方法があれば、私は感謝します。以下の例では、_contextフィールドはIComponentContext型です。

ここで最良のオプションは、キーと定期的な「型指定された」サービスの両方使用してアイテムを登録することである
public IEnumerable<T> ResolveAll<T>() 
    { 
     // We're going to find each service which was registered 
     // with a key, and for those which match the type T we'll store the key 
     // and later supplement the default output with individual resolve calls to those 
     // keyed services 
     var allKeys = new List<object>(); 
     foreach (var componentRegistration in _context.ComponentRegistry.Registrations) 
     { 
      // Get the services which match the KeyedService type 
      var typedServices = componentRegistration.Services.Where(x => x is KeyedService).Cast<KeyedService>(); 
      // Add the key to our list so long as the registration is for the correct type T 
      allKeys.AddRange(typedServices.Where(y => y.ServiceType == typeof (T)).Select(x => x.ServiceKey)); 
     } 

     // Get the default resolution output which resolves all un-keyed services 
     var allUnKeyedServices = new List<T>(_context.Resolve<IEnumerable<T>>()); 
     // Add the ones which were registered with a key 
     allUnKeyedServices.AddRange(allKeys.Select(key => _context.ResolveKeyed<T>(key))); 

     // Return the total resultset 
     return allUnKeyedServices; 
    } 
+1

よりもむしろ'解決を使用して 'と' ResolveKeyed 'ResolveComponent()'メソッドの使用を検討するかもしれません。これにより、同じサービス(または同じキー)に対して複数の実装が存在するケースをより適切に扱うことができます。 –

0

なお、以下に示すように、あなたがAs<T>()方法とNamed<T>()方法を組み合わせることができますように思われる:、ここで `)(お)(

[TestMethod] 
    public void ResolveTests() 
    { 
     var builder = new ContainerBuilder(); 
     builder.RegisterType<ClassA1>().As<IClassA>().Named<IClassA>("1"); 
     builder.RegisterType<ClassA2>().As<IClassA>().Named<IClassA>("2"); 
     builder.RegisterType<ClassA3>().As<IClassA>().Named<IClassA>("3"); 
     var container = builder.Build(); 

     var allInstances = container.Resolve<IEnumerable<IClassA>>(); 
     allInstances.Count().Should().Be(3); 

     container.ResolveNamed<IClassA>("1").Should().BeAssignableTo<ClassA1>(); 
     container.ResolveNamed<IClassA>("2").Should().BeAssignableTo<ClassA2>(); 
     container.ResolveNamed<IClassA>("3").Should().BeAssignableTo<ClassA3>(); 
    }