Autofac None of the constructors found with 'Autofac.Core.Activators.Reflection.DefaultConstructorFinder'
I am getting back to Autofac issues despite having used it very much like a year and really need advice.
I choose selection via attributes. The difference this time is that one of the registrations uses IIndex to select the most appropriate interface for the task at hand based on the LoginState enumeration. This value is provided through an attribute.
You can think of it as a very simple Autofac based autorun.
Due to the choice of access right, I have the following extension method, which gets the type through the presence of the attribute and the value of the attribute:
public static class ContainerBuilderEnumerateAttributedTypes
{
#region EnumerateAttributedTypes(builder, action)
[DebuggerStepThrough]
public static void EnumerateAttributedTypes<TAttribute>(this ContainerBuilder builder,
Action<Type, TAttribute> action) where TAttribute : Attribute
{
var typesAndAttributes = Assembly
.GetExecutingAssembly()
.GetTypes()
.Where(type => type.GetCustomAttributes<TAttribute>(false).Any())
.Select(type => new { Type = type, Attribute = type.GetCustomAttributes<TAttribute>(false).First() });
foreach (var typeAndAtttribute in typesAndAttributes)
{
action(typeAndAtttribute.Type, typeAndAtttribute.Attribute);
}
}
#endregion
#region EnumerateAttributedTypes(builder, inherit, action)
[DebuggerStepThrough]
public static void EnumerateAttributedTypes<TAttribute>(this ContainerBuilder builder,
bool inherit, Action<Type, TAttribute> action) where TAttribute : Attribute
{
var typesAndAttributes = Assembly
.GetExecutingAssembly()
.GetTypes()
.Where(type => type.GetCustomAttributes<TAttribute>(inherit).Any())
.Select(type => new { Type = type, Attribute = type.GetCustomAttributes<TAttribute>(inherit).First() });
foreach (var typeAndAtttribute in typesAndAttributes)
{
action(typeAndAtttribute.Type, typeAndAtttribute.Attribute);
}
}
#endregion
}
During Global.asax.cs I call builder.RegisterModule, which in terms calls builder.RegisterModule.
It has the following:
public class LogicAutofacModule : Module
{
#region Load
protected override void Load(ContainerBuilder builder)
{
builder.EnumerateAttributedTypes<DispatcherAttribute>((type, attribute) =>
{
var @interface = type.GetInterfaces().First();
// ReSharper disable once ConvertToLambdaExpression
builder
.RegisterType(type)
.As(@interface);
});
builder.EnumerateAttributedTypes<LogicAttribute>((type, attribute) =>
{
var @interface = type.GetInterfaces().First();
// ReSharper disable once ConvertToLambdaExpression
builder
.RegisterType(type)
.Keyed(attribute.State, @interface)
.As(@interface);
});
}
#endregion
There are two instances of IDispatcher:
IIndex<LoginState, ILogic<AuthenticateContext, AuthenticateResult>>
and
IIndex<LoginState, ILogic<AuthenticateIncurringChargeContext, AuthenticateIncurringChargeResult>> _handlers;
LoginState, if specified via attribute, if applicable via
[LogicDispatcher (LogicState.InvalidCredentials)]
etc.
Regardless of how I do it, even going back to the most basic registration method, I get "None of the constructors found with
Autofac.Core.Activators.Reflection.DefaultConstructorFinder error message.
This has never happened before ... please advise or request more information.
Follow-up thought ... here is an example ILogic implementation:
[Logic(LoginState.InvalidAccount)]
public class AuthenticateInvalidAccount : ILogic<AuthenticateContext, AuthenticateResult>
{
#region Execute
public AuthenticateResult Execute(AuthenticateContext context, LoginResponse response)
{
return new AuthenticateResult
{
State = State.InvalidAccount
};
}
#endregion
}
And the dispatcher instance:
[Dispatcher]
public class AuthenticateDispatcher : IDispatcher<AuthenticateContext, AuthenticateResult>
{
#region Fields
private readonly IIndex<LoginState, ILogic<AuthenticateContext, AuthenticateResult>> _handlers;
#endregion
#region Constructors
public AuthenticateDispatcher(IIndex<LoginState, ILogic<AuthenticateContext, AuthenticateResult>> handlers)
{
_handlers = handlers;
}
#endregion
#region Dispatch
public AuthenticateResult Dispatch(AuthenticateContext context)
{
var service = new AccountServiceClient();
var response = service.Invoke(client => client.Login(context.Username, context.Password));
var logic = _handlers[response.LoginState];
var result = logic.Execute(context, response);
return result;
}
#endregion
}
The service is super simple:
[ErrorHandled]
public class Service : IService
{
#region Fields
private readonly IDispatcher<AuthenticateContext, AuthenticateResult> _authenticateDispatcher;
private readonly IDispatcher<AuthenticateIncurringChargeContext, AuthenticateIncurringChargeResult> _authenticateIncurringChargeDispatcher;
#endregion
#region Constructor
public Service(
IDispatcher<AuthenticateContext, AuthenticateResult> authenticateDispatcher,
IDispatcher<AuthenticateIncurringChargeContext, AuthenticateIncurringChargeResult> authenticateIncurringChargeDispatcher)
{
_authenticateDispatcher = authenticateDispatcher;
_authenticateIncurringChargeDispatcher = authenticateIncurringChargeDispatcher;
}
#endregion
#region Authenticate
public AuthenticateResponse Authenticate(AuthenticateRequest request)
{
var context = request.Map<AuthenticateContext>();
var result = _authenticateDispatcher.Dispatch(context);
var response = result.Map<AuthenticateResponse>();
return response;
throw new NotImplementedException();
}
#endregion
#region AuthenticateIncurringCharge
public AuthenticateIncurringChargeResponse AuthenticateIncurringCharge(AuthenticateIncurringChargeRequest request)
{
//var context = request.Map<AuthenticateIncurringChargeContext>();
//var result = _authenticateIncurringChargeDispatcher.Dispatch(context);
//var response = result.Map<AuthenticateIncurringChargeResponse>();
//return response;
throw new NotImplementedException();
}
#endregion
}
source to share