简体   繁体   中英

Autofac Named Registration Failing

I am trying to used named registrations and a func to register an implementation I need.

 builder
       .RegisterType<AImpl>().Named<IMyInterface>("all");

        builder
       .RegisterType<BImpl>().Named<IMyInterface>("all");

        builder
            .Register(c =>
            {
                var myImpl= c.ResolveNamed<IEnumerable<IMyInterface>>("all").FirstOrDefault(a => a.Code == "SOMESTRING");
                if (myImpl== null)
                    throw new MySpecificException("SOMESTRING");
                return myImpl;
            })
            .AsImplementedInterfaces();

I get the following exception when i try resolve:

        var myImpl = c.Resolve<IMyInterface>();

An exception of type 'Autofac.Core.Registration.ComponentNotRegisteredException' occurred in Autofac.dll but was not handled in user code

Additional information: The requested service 'MyNameSpace.IMyInterface' 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.

Anyone any idea why this is failing? The inner func resolves do work correctly so it isnt that!

Thanks Neil

Maybe I do not understand the question, but I think you're doing it wrong. RegisterNamed should be used in order to get an implementation by a string tag.

In your example you have:

builder.RegisterType<AImpl>().Named<IMyInterface>("all");
builder.RegisterType<BImpl>().Named<IMyInterface>("all");

This doesn't make sense to me. You should call something like:

builder.RegisterType<AImpl>().Named<IMyInterface>("TheNameIsA");
builder.RegisterType<BImpl>().Named<IMyInterface>("TheNameIsB");

And, in the consuming class, you can require in the constructor an:

public MyComponent(IIndex<string, IMyInterface> myInterfaceIndex)
...

and require from it the component you want as:

var a = myInterfaceIndex["TheNameIsA"];
var b = myInterfaceIndex["TheNameIsB"];

Alternatively, you can require (via constructor or property injection) an ILifetimeScope and use it for dynamic resolution as:

var a = myLifetimeScope.ResolveNamed<IMyInterface>("TheNameIsA");

Note, unrelated to the question: This, obviously, if you REALLY need to have more than one implementation available simultaneously. If you need only one of the two, you should use a Module and configure it so it will register only one of the two implementations.

Edit: The exception you are getting is (should be) because you are not calling ResolveNamed. You are asking for a IMyInterface, but you didn't registered an IMyInterface without name. So you get the exception. I'm not 100% confident, but I dare to say I'm pretty confident about this.

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