Разрешить все данные Тип

Из документации Autofac Я вижу, как получить все регистрации для класса T:

public T[] ResolveAll<t>()
{
 return _container.Resolve<ienumerable<t>>().ToArray();
}
</ienumerable<t></t>

Но когда у меня есть только доступный тип, как я могу получить эквивалентные результаты?

public Array ResolveAll(Type service)
{
 return _container.Resolve( ??? 
}

Я пытаюсь реализовать класс-оболочку, у которого есть предопределенный интерфейс.

ИЗМЕНИТЬ

Для быстрой справки ответ Мэтью Уотсона (с соответствующими идеями Дэвида Л):

public Array ResolveAll(Type service)
{
 var typeToResolve = typeof(IEnumerable<>).MakeGenericType(service);
 return _container.Resolve(typeToResolve) as Array; 
}
2 ответа

Вот пример. Я добавил утверждения, чтобы доказать, что типы, возвращаемые из ResolveAll<t>(this IContainer self)</t>, одинаковы (и в том же порядке), что и те, которые возвращаются из ResolveAll(this IContainer self, Type type):

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using Autofac;
using Autofac.Core;
namespace AutofacTrial
{
 public abstract class Base
 {
 public abstract string Name { get; }
 public override string ToString()
 {
 return Name;
 }
 }
 public sealed class Derived1: Base
 {
 public override string Name
 {
 get
 {
 return "Derived1";
 }
 }
 }
 public sealed class Derived2: Base
 {
 public override string Name
 {
 get
 {
 return "Derived2";
 }
 }
 }
 public sealed class Derived3: Base
 {
 public override string Name
 {
 get
 {
 return "Derived3";
 }
 }
 }
 static class Program
 {
 static void Main()
 {
 var builder = new ContainerBuilder();
 builder.RegisterType<derived1>().As();
 builder.RegisterType<derived2>().As();
 builder.RegisterType<derived3>().As();
 var container = builder.Build();
 var array1 = container.ResolveAll(typeof(Base));
 var array2 = container.ResolveAll();
 Trace.Assert(array1.Length == 3);
 Trace.Assert(array2.Length == 3);
 for (int i = 0; i < array1.Length; ++i)
 {
 Trace.Assert(array1[i].GetType() == array2[i].GetType());
 Console.WriteLine(array1[i]);
 }
 }
 public static T[] ResolveAll<t>(this IContainer self)
 {
 return self.Resolve<ienumerable<t>>().ToArray();
 }
 public static object[] ResolveAll(this IContainer self, Type type)
 {
 Type enumerableOfType = typeof(IEnumerable<>).MakeGenericType(type);
 return (object[]) self.ResolveService(new TypedService(enumerableOfType));
 }
 }
}
</ienumerable<t></t></derived3></derived2></derived1>

Реализация поднижения является тем же самым

Я также использовал Reflector, чтобы посмотреть на реализацию Resolve<ienumerable<t>>()</ienumerable<t>, и это завершает это:

public static TService Resolve<tservice>(this IComponentContext context, IEnumerable<parameter> parameters)
{
 return (TService) context.Resolve(typeof(TService), parameters);
}
</parameter></tservice>

который вызывает:

public static object Resolve(this IComponentContext context, Type serviceType, IEnumerable<parameter> parameters)
{
 return context.ResolveService(new TypedService(serviceType), parameters);
}
</parameter>

Итак, эти два должны быть эквивалентными, поскольку они реализованы таким образом.


Вы можете вызвать _container.Resolve, вызвав ваш завернутый метод через отражение (MSDN), но при этом вы потеряете свой компилятор безопасности времени.

public class Container
{
 public T[] ResolveAll<t>()
 {
 return _container.Resolve<ienumerable<t>>().ToArray();
 }
 public object ResolveAllGeneric(Type t)
 {
 MethodInfo method = GetType().GetMethod("ResolveAll")
 .MakeGenericMethod(new Type[] { t });
 return method.Invoke(this, new object[] { });
 } 
}
</ienumerable<t></t>

licensed under cc by-sa 3.0 with attribution.