Как получить тип от Autofa c Регистрации, используемые для регистрации - PullRequest
0 голосов
/ 14 апреля 2020

Как я могу получить тип, который использовался для регистрации класса в контейнере, из container.ComponentRegistry.Registrations?

    // I have some types like

    interface IBase { }
    interface IA : IBase { }
    interface IB : IBase { }

    class A : IA { }
    class B : IB { }

    class Program
    {
        static void Main(string[] args)
        {
            var builder = new ContainerBuilder();

            // Registering types as interface implementations
            builder.RegisterType<A>().As<IA>();
            builder.RegisterType<B>().As<IB>();

            var c = builder.Build();


            // Trying to get all registered types assignable to IBase
            var types = c.ComponentRegistry.Registrations
                .Where(r => typeof(IBase).IsAssignableFrom(r.Activator.LimitType))
                .Select(r => r.Activator.LimitType); // Returns A insted of IA

            // Trying to Resolve all types
            types.Select(t => c.Resolve(t) as IBase).ToList();
        }
    }

Поскольку .Activator.LimitType возвращает тип A insted типа IA, который использовался в контейнере Я получаю исключение

Autofac.Core.Registration.ComponentNotRegisteredException : The requested service 'A' has not been registered. To avoid this exception, either register a component to provide the service, check for service registration using IsRegistered(), or use the ResolveOptional() method to resolve an optional dependency.

1 Ответ

1 голос
/ 14 апреля 2020

Один из подходов - убедиться, что ваш регистр A не только против IA, но также против IBase (и то же самое для B).

Затем решение IEnumerable<IBase> найдет A и B:

using System;
using System.Collections.Generic;
using System.Linq;
using Autofac;

namespace WatCode
{
    interface IBase { }
    interface IA : IBase { }
    interface IB : IBase { }

    class A : IA { }
    class B : IB { }

    class Program
    {
        static void Main(string[] args)
        {
            var builder = new ContainerBuilder();

            // Registering types as interface implementations
            builder.RegisterType<A>().AsImplementedInterfaces(); // register against IA and IBase
            builder.RegisterType<B>().AsImplementedInterfaces(); // register against IB and IBase

            var c = builder.Build();

            var matching = c.Resolve<IEnumerable<IBase>>();

            Console.WriteLine(matching.Count());
        }

    }
}

Выше будет записывать 2 в консоль, поскольку она находит оба совпадения.

...