简体   繁体   中英

How to get a type from Autofac Registrations used for registration

How can I get type that was used to register class in container from 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();
        }
    }

Because .Activator.LimitType returns type A insted of type IA which was used in container, i getting an Exception

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.

One approach is to ensure your register A not just against IA but also against IBase (and the same for B ).

Then resolving IEnumerable<IBase> will find both A and 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());
        }

    }
}

Above will write 2 to the console since it finds both matches.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM