Allow All Data Type

From the Autofac documentation I can see how to get all registrations for class T:

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

But when I have only the type available, how can I get equivalent results?

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

I am trying to implement a wrapper class that has a predefined interface.


EDIT

For quick reference, Matthew Watson's answer (with relevant ideas from David L):

public Array ResolveAll(Type service)
{
    var typeToResolve = typeof(IEnumerable<>).MakeGenericType(service);
    return _container.Resolve(typeToResolve) as Array;    
}
+4
source share
2 answers

Here is an example. I added statements to prove that the types returned from ResolveAll<T>(this IContainer self)are the same (and in the same order) as those returned from 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<Base>();
            builder.RegisterType<Derived2>().As<Base>();
            builder.RegisterType<Derived3>().As<Base>();

            var container = builder.Build();

            var array1 = container.ResolveAll(typeof(Base));
            var array2 = container.ResolveAll<Base>();

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

The implementation of a downgrade is the same

Reflector, Resolve<IEnumerable<T>>(), :

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

:

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

, , .

+1

_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[] { });
    } 
}
+1

All Articles