Skip to content

Instantly share code, notes, and snippets.

@GeorgeTsiokos
Last active November 30, 2016 14:54
Show Gist options
  • Save GeorgeTsiokos/2c0fd579442603f6c1fa41232cd7abd5 to your computer and use it in GitHub Desktop.
Save GeorgeTsiokos/2c0fd579442603f6c1fa41232cd7abd5 to your computer and use it in GitHub Desktop.
Autofac: use constructor parameter names to resolve named dependencies
public static void WithNamedParameters<TImplementer> (this IRegistrationBuilder<TImplementer, ReflectionActivatorData, SingleRegistrationStyle> registrationBuilder) {
var activatorData = registrationBuilder.ActivatorData;
var implementationType = activatorData.ImplementationType;
var constructors = activatorData.ConstructorFinder.FindConstructors (implementationType);
registrationBuilder.OnPreparing (preparingEventArgs => OnPreparing (constructors,
activatorData.ConstructorSelector,
preparingEventArgs));
}
private static void OnPreparing (ConstructorInfo[] constructors, IConstructorSelector constructorSelector, PreparingEventArgs preparingEventArgs) {
var componentContext = preparingEventArgs.Context;
var constructorBinding = GetConstructorParameterBinding (constructors,
constructorSelector,
preparingEventArgs);
var constructorParameters = constructorBinding.TargetConstructor.GetParameters ();
var namedAndRegisteredParameters = constructorParameters.Where (constructorParameter => IsRegisteredWithName (constructorParameter,
componentContext));
preparingEventArgs.Parameters = namedAndRegisteredParameters.Select (CreateResolvedParameter);
}
private static ConstructorParameterBinding GetConstructorParameterBinding (ConstructorInfo[] constructors, IConstructorSelector constructorSelector, PreparingEventArgs preparingEventArgs) {
var constructorParameterBindings = constructors.Select (constructorInfo => CreateConstructorParameterBinding (constructorInfo,
preparingEventArgs));
return constructorSelector.SelectConstructorBinding (constructorParameterBindings.ToArray ());
}
private static bool IsRegisteredWithName (ParameterInfo constructorParameter, IComponentContext componentContext) {
return componentContext.IsRegisteredWithName (constructorParameter.Name,
constructorParameter.ParameterType);
}
private static ConstructorParameterBinding CreateConstructorParameterBinding (ConstructorInfo constructorInfo, PreparingEventArgs preparingEventArgs) {
return new ConstructorParameterBinding (constructorInfo,
preparingEventArgs.Parameters,
preparingEventArgs.Context);
}
private static ResolvedParameter CreateResolvedParameter (ParameterInfo parameter) {
return new ResolvedParameter ((info, context) => info.ParameterType == parameter.ParameterType && info.Name == parameter.Name,
(info, context) => context.ResolveNamed (parameter.Name,
parameter.ParameterType));
}
@GeorgeTsiokos
Copy link
Author

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment