web-dev-qa-db-ja.com

特定のインターフェースを実装するすべての登録済みオブジェクトのリストを取得します

次のことを考慮してください

builder.Register(c => new A());
builder.Register(c => new B());
builder.Register(c => new C());

BCはどちらもISomeInterfaceです。

ここで、IEnumerableを実装するすべての登録済みオブジェクトのISomeInterfaceを取得したいと思います。

Autofacでこれをどのように達成できますか?

14
kasperhj

これを試しただけで、機能し、ライフタイムのコンテキストに依存しません。

代わりにActivatorを使用してタイプを列挙します

var types = con.ComponentRegistry.Registrations
     .Where(r => typeof(ISomeInterface).IsAssignableFrom(r.Activator.LimitType))
     .Select(r => r.Activator.LimitType);

次に解決するには:

IEnumerable<ISomeInterface> lst = types.Select(t => con.Resolve(t) as ISomeInterface);
24
catflier

あなたが持っている場合

container.Register(c => new A()).As<ISomeInterface>();
container.Register(c => new B()).As<ISomeInterface>();

それからあなたがするとき

var classes = container.Resolve<IEnumerable<ISomeInterface>>();

AとBを含むISomeInterfaceのリストである変数を取得します

25
Tim Burkhart

これが私がそれをした方法です。

var l = Container.ComponentRegistry.Registrations
          .SelectMany(x => x.Services)
          .OfType<IServiceWithType>()
          .Where(x => 
                 x.ServiceType.GetInterface(typeof(ISomeInterface).Name) != null)
          .Select(c => (ISomeInterface) c.ServiceType);
3
kasperhj

継承されたクラスに関してこれを検索している人のための明確化

例:

    public static IEnumerable<Type> GetTypesInherit<T>(this Assembly assembly)
    {
        var types = Assembly.GetTypes()
            .Where(myType => myType.IsClass && !myType.IsAbstract && myType.IsSubclassOf(typeof(T)))
            .ToList();

        return types;
    }

インストーラー:

    public static IContainer Install()
    {
        var builder = new ContainerBuilder();
        var executingAssembly = Assembly.GetExecutingAssembly();

        var testScreens = executingAssembly.GetTypesInherit<TestScreen>();
        foreach (var testScreen in testScreens)
        {                   
            builder.RegisterType(testScreen).As<TestScreen>();
        }

        var container = builder.Build();
        return container;
    }

使用法(暗黙的):

  public class MainViewModel(IEnumerable<TestScreen> testScreens) 
  {}
0
eran otzap

いくつかのコンテキストに基づいて解決する必要がありました。わずかな違い...

 builder.RegisterAssemblyTypes(Assembly.GetAssembly(typeof(ISomeStrategy)))
   .Where(t => typeof(ISomeStrategy).IsAssignableFrom(t))
   .AsSelf();

 builder.Register<Func<SomeEnum, ISomeStrategy>>(c =>
 {
    var types = c.ComponentRegistry.Registrations
      .Where(r => typeof(ISomeStrategy).IsAssignableFrom(r.Activator.LimitType))
      .Select(r => r.Activator.LimitType);

    ISomeStrategy[] lst = types.Select(t => c.Resolve(t) as ISomeStrategy).ToArray();

    return (someEnum) =>
    {
      return lst.FirstOrDefault(x => x.CanProcess(someEnum));
    };
 });

次に、戦略を使用してクラスを作成します

 public SomeProvider(Func<SomeType, ISomeStrategy> someFactory)
 {
    _someFactory = someFactory;
 }

 public void DoSomething(SomeType someType)
 {
    var strategy = _someFactory(someType);
    strategy.DoIt();
 }
0
Devgig