Support multiple constructors with reflection-based component registration
See original GitHub issueSupport multiple constructors where the constructor parameters are able to be obtained from the container and based on the supplied autofac parameters. The variable nature of the autofac parameters would decide which constructor to select.
For example, given a simple type with two public constructors:
public class TwoConstructors
{
readonly object _value;
public TwoConstructors(IA value) => _value = value;
public TwoConstructors(IB value) => _value = value;
public override string ToString() => _value.ToString();
}
with simple types for the constructor parameters:
public interface IA { }
public interface IB { }
public class A : IA { public override string ToString() => "A"; }
public class B : IB { public override string ToString() => "B"; }
with reflection-based registration:
var containerBuilder = new ContainerBuilder();
containerBuilder.RegisterType<A>().As<IA>();
containerBuilder.RegisterType<B>().As<IB>();
It would be great if this reflection-based registration:
containerBuilder.RegisterType<TwoConstructors>();
would behave like this delegate-based registration:
containerBuilder.Register((componentContext, parameters) =>
{
var ia = parameters.OfType<TypedParameter>().Where(typedParameter => typedParameter.Type == typeof(IA)).Select(typedParameter => (IA)typedParameter.Value).FirstOrDefault();
if (ia != null)
return new TwoConstructors(ia);
var ib = parameters.OfType<TypedParameter>().Where(typedParameter => typedParameter.Type == typeof(IB)).Select(typedParameter => (IB)typedParameter.Value).FirstOrDefault();
if (ib != null)
return new TwoConstructors(ib);
throw new DependencyResolutionException("Missing IA or IB parameter");
});
Today we receive the following expected exception:
Unhandled Exception: Autofac.Core.DependencyResolutionException: An error occurred during the activation of a particular registration. See the inner exception for details. Registration: Activator = TwoConstructors (ReflectionActivator), Services = [TwoConstructors], Lifetime = Autofac.Core.Lifetime.CurrentScopeLifetime, Sharing = None, Ownership = OwnedByLifetimeScope ---> Cannot choose between multiple constructors with equal length 1 on type 'TwoConstructors'. Select the constructor explicitly, with the UsingConstructor() configuration method, when the component is registered.
- reflection-based component registration does not currently support multiple constructors
Example usage (works with delegate-based registration):
var container = containerBuilder.Build();
Console.WriteLine(container.Resolve<TwoConstructors>(TypedParameter.From(container.Resolve<IA>())));
Console.WriteLine(container.Resolve<TwoConstructors>(TypedParameter.From(container.Resolve<IB>())));
Console.WriteLine(container.Resolve<TwoConstructors>()); // throws expected exception
Console.WriteLine(container.Resolve<Func<IA, TwoConstructors>>()(container.Resolve<IA>()));
Console.WriteLine(container.Resolve<Func<IB, TwoConstructors>>()(container.Resolve<IB>()));
Console.WriteLine(container.Resolve<Func<TwoConstructors>>()); // returns a func that will always throw the expected exception
Issue Analytics
- State:
- Created 6 years ago
- Comments:6 (1 by maintainers)
Top Results From Across the Web
c# - Use Activator.CreateInstance() and support multiple ...
Now there is a new requirement: The constructor of myType can have multiple parameters. One of them has to accept an IConfiguration object....
Read more >Registration Concepts — Autofac 7.0.0 documentation
When using reflection-based components, Autofac automatically uses the constructor for your class with the most parameters that are able to be obtained from ......
Read more >Dependency Injection anti-pattern: multiple constructors
When Dependency Injection is applied correctly and completely, it is important that each type only has one constructor—multiple constructors ...
Read more >Passing Parameters to Register
When you register a reflection-based component, the constructor of the type may require a parameter that can't be resolved from the container.
Read more >How do I handle multiple constructors where each is ...
Normally, to do this I would set up a base class ( Shape ) and two derived classes ( ConfigurableParallelogram and DisplayOnlyParallelogram )....
Read more >
Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free
Top Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found
+1
+1. Should be very helpful