Dion
Dion

Reputation: 954

None of the constructors found with 'Autofac.Core.Activators.Reflection.DefaultConstructorFinder'

When I try to set a PARAMETER using the Xml Configuration I get the following error:

None of the constructors found with 'Autofac.Core.Activators.Reflection.DefaultConstructorFinder' on type 'LM.AM.Core.Services.EmailService' can be invoked with the available services and parameters: Cannot resolve parameter 'System.String testSmtp' of constructor 'Void .ctor(System.String)'.

Here are the relevant files:

web.config

  <configSections>
    <section name="autofac" type="Autofac.Configuration.SectionHandler, Autofac.Configuration" />
  </configSections>

  <autofac>
    <components>
      <component type="LM.AM.Core.Services.EmailService , LM.AM.Core" service="LM.AM.Core.Infrastructure.Services.IEmailService , LM.AM.Core.Infrastructure">
        <parameters>
          <parameter name="testSmtp" value="abc" />
        </parameters>
      </component>
    </components>
  </autofac>

Service Class

public class EmailService : IEmailService
{
    public string _testSmtp;

    public EmailService (string testSmtp)
    {
        _testSmtp = testSmtp;
    }
}

Registration

builder.RegisterType<EmailService>().As<IEmailService>().SingleInstance();

Global.asax

var builder = new ContainerBuilder();
builder.RegisterModule(new ConfigurationSettingsReader("autofac"));

builder.RegisterModule<Core.ModuleInstaller>();

builder.RegisterControllers(typeof(MvcApplication).Assembly);
AutofacContainer.Container = builder.Build();

var emailSvc = AutofacContainer.Container.Resolve<IEmailService>();

I've checked the container is aware of the xml parameter and I've followed the Wiki as close as I can, but for some reason the parameter is not resolving on the only constructor and I'm receiving the above error.

This should be pretty simple to get going. Can anyone provide some suggestions on what I can try to get this working?

Upvotes: 34

Views: 87246

Answers (5)

Durkee
Durkee

Reputation: 1

I had this issue, and it turned out I was not using the Interface type in the constructor. For example,

Not using constructor params as Interface (Bad):

namespace Acme.Services
    {
       public class MyWebHookHandler : IMyWebHookHandler
       {
         private readonly HttpClientFactory _httpClientFactory;

         public MyWebHookHandler(HttpClientFactory _httpClientFactory)
         {
            _httpClientFactory = httpClientFactory;
         }
    }
 }

Using constructor params as Interface (Good):

namespace Acme.Services
    {
       public class MyWebHookHandler : IMyWebHookHandler
       {
         private readonly IHttpClientFactory _httpClientFactory;

         public MyWebHookHandler(IHttpClientFactory _httpClientFactory)
         {
            _httpClientFactory = httpClientFactory;
         }
    }
 }

Upvotes: 0

Amitha Padiyar
Amitha Padiyar

Reputation: 11

Adding the service with appropriate scope(Singleton,Scoped,Transient) to the specified IServiceCollection instance helped to resolve this issue. Something like below:

public static IServiceCollection YourServiceCollectionExtensionMethod(this IServiceCollection services)
{
    services.AddTransient<IEmailService, EmailService>();
}

Hope this helps!

Upvotes: 0

David Hyde
David Hyde

Reputation: 922

My registrations were all good, but I had referenced the concrete class instead of the interface in my constructor - Missed the 'I'. Hope this answer helps someone save 5 minutes of effort one day.

Upvotes: 1

fruitbatinshades
fruitbatinshades

Reputation: 131

I had created a constructor where there was none before and made it private, therefore there was default constructor so I got this error. Had to make my constructor public.

Upvotes: 8

nemesv
nemesv

Reputation: 139748

You have regiestered your EmailService two times.

Once in the web.config and once with

builder.RegisterType<EmailService>().As<IEmailService>().SingleInstance();

If you have the line above in the Core.ModuleInstaller then it will override the web.config configuration. And because here you haven't specified the parameter Autofac throws an exception.

So to solve this just remove the EmailService registration from the Core.ModuleInstaller module.

If you use the Core.ModuleInstaller multiple places and you need to have the EmailService registration there then you need to change the order of the Module loading:

var builder = new ContainerBuilder();
builder.RegisterModule<Core.ModuleInstaller>();
builder.RegisterModule(new ConfigurationSettingsReader("autofac"));

or tell Autofac to not override the registration of EmailService if it already exists with PreserveExistingDefaults:

builder.RegisterType<EmailService>().As<IEmailService>()
       .SingleInstance().PreserveExistingDefaults();

Upvotes: 32

Related Questions