autofac – 解决所有给定的类型


Autofac documentation我可以看到如何获得T类的所有注册:

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

但是当我只有Type可用时,我怎样才能获得相同的结果?

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

我正在尝试实现一个具有预定义接口的包装器类.

编辑

为了快速参考,Matthew Watson(来自David L的相关想法)的答案是:

public Array ResolveAll(Type service)
{
    var typeToResolve = typeof(IEnumerable<>).MakeGenericType(service);
    return _container.Resolve(typeToResolve) as Array;    
}

最佳答案 这是一个例子.我添加了断言以证明从ResolveAll< T>(此IContainer self)返回的类型与ResolveAll(此IContainer self,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));
        }
    }
}

基础实施是相同的

我还使用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);
}

所以两者必须是等价的,因为它们是以这种方式实现的.

点赞