JasperFx / lamar

Fast Inversion of Control Tool and Successor to StructureMap
https://jasperfx.github.io/lamar
MIT License
566 stars 117 forks source link

System.MissingMethodException: Constructor on type XXXXXX not found. #210

Closed mdelprado-emphasys closed 4 years ago

mdelprado-emphasys commented 4 years ago

We are tying to migrate our api project from Net Core 2.0 to 3.0. We were using StructureMap before so we have modified the application according to the documentation to use Lamar. We have configured Lamar in the Program file like this:

public static IHostBuilder CreateHostBuilder(string[] args) =>
       Microsoft.Extensions.Hosting.Host.CreateDefaultBuilder(args)
            .UseLamar()
            .ConfigureWebHostDefaults(webBuilder =>
            {
                webBuilder
                .UseContentRoot(Directory.GetCurrentDirectory())
                .UseSetting("detailedErrors", "true")
                .UseIISIntegration()
                .CaptureStartupErrors(true)
                .UseStartup<Startup>();
            });

And Startup class like this:

public void ConfigureContainer(ServiceRegistry registry)
{
     registry.Scan(_ =>
     {
         _.AssemblyContainingType(typeof(Startup)); //this is what we had with StructureMap. Tried TheCallingAssembly() with Lamar and it didn't make a difference
         _.WithDefaultConventions();
         _.AddAllTypesOf<IMappingDefinition>();
     });
     registry.For<IConfigurationRoot>().Use(this.Configuration);
}

This is pseudo code of one of the services we have:

 public interface IAuthService
{
    /*not relevant code here*/
}

And concrete class

public class AuthService : IAuthService
{
    /*not relevant code here*/

    public AuthService(ILogger<AuthService> logger, IOptions<AuthServiceSettings> authServiceSettings, IDbContext dbContext)
    {
        this.logger = logger;
        this.authServiceSettings = authServiceSettings.Value;
        this.DbContext = dbContext;
    }

    /*not relevant code here*/

}

My development environment is hosted locally on IIS and I'm are getting this error when I hit the api

Application '/LM/W3SVC/1/ROOT/API' with physical root 'C:\inetpub\wwwroot\api\' hit unexpected managed exception, exception code = '0xe0434352'. First 30KB characters of captured stdout and stderr logs: System.MissingMethodException: Constructor on type 'RestApiHost.Services.AuthService' not found. at System.RuntimeType.CreateInstanceImpl(BindingFlags bindingAttr, Binder binder, Object[] args, CultureInfo culture) at System.Activator.CreateInstance(Type type, BindingFlags bindingAttr, Binder binder, Object[] args, CultureInfo culture, Object[] activationAttributes) at Lamar.IoC.Instances.ConstructorInstance.quickResolve(Scope scope) at Lamar.IoC.Instances.ConstructorInstance.QuickResolve(Scope scope) at Lamar.IoC.Instances.ConstructorInstance.<>cDisplayClass18_0.b0(CtorArg x) at System.Linq.Enumerable.SelectArrayIterator2.ToArray() at System.Linq.Enumerable.ToArray[TSource](IEnumerable1 source) at Lamar.IoC.Instances.ConstructorInstance.quickResolve(Scope scope) at Lamar.IoC.Instances.ConstructorInstance.QuickResolve(Scope scope) at Lamar.IoC.Enumerables.ListInstance`1.<>cDisplayClass5_0.b0(Instance x) at System.Linq.Enumerable.SelectArrayIterator2.ToList() at System.Linq.Enumerable.ToList[TSource](IEnumerable1 source) at Lamar.IoC.Enumerables.ListInstance1.QuickResolve(Scope scope) at Lamar.IoC.Instances.ConstructorInstance.<>c__DisplayClass18_0.<quickResolve>b__0(CtorArg x) at System.Linq.Enumerable.SelectArrayIterator2.ToArray() at System.Linq.Enumerable.ToArray[TSource](IEnumerable1 source) at Lamar.IoC.Instances.ConstructorInstance.quickResolve(Scope scope) at Lamar.IoC.Instances.ConstructorInstance.QuickResolve(Scope scope) at Lamar.IoC.Enumerables.ListInstance1.<>cDisplayClass5_0.b0(Instance x) at System.Linq.Enumerable.SelectArrayIterator2.ToList() at System.Linq.Enumerable.ToList[TSource](IEnumerable1 source) at Lamar.IoC.Enumerables.ListInstance`1.QuickResolve(Scope scope) at Lamar.IoC.Instances.ConstructorInstance.<>cDisplayClass18_0.b0(CtorArg x) at System.Linq.Enumerable.SelectArrayIterator2.ToArray() at System.Linq.Enumerable.ToArray[TSource](IEnumerable1 source) at Lamar.IoC.Instances.ConstructorInstance.quickResolve(Scope scope) at Lamar.IoC.Instances.ConstructorInstance.QuickResolve(Scope scope) at Lamar.IoC.Instances.ConstructorInstance.<>cDisplayClass18_0.b0(CtorArg x) at System.Linq.Enumerable.SelectArrayIterator2.ToArray() at System.Linq.Enumerable.ToArray[TSource](IEnumerable1 source) at Lamar.IoC.Instances.ConstructorInstance.quickResolve(Scope scope) at Lamar.IoC.Instances.ConstructorInstance.QuickResolve(Scope scope) at Lamar.IoC.Frames.InjectedServiceField.ToVariableExpression(LambdaDefinition definition) at LamarCodeGeneration.Expressions.LambdaDefinition.ExpressionFor(Variable variable) at System.Linq.Enumerable.SelectArrayIterator2.ToArray() at System.Linq.Enumerable.ToArray[TSource](IEnumerable1 source) at System.Dynamic.Utils.CollectionExtensions.ToReadOnly[T](IEnumerable1 enumerable) at System.Linq.Expressions.Expression.NewArrayInit(Type type, IEnumerable1 initializers) at Lamar.IoC.Frames.ListAssignmentFrame`1.WriteExpressions(LambdaDefinition definition) at Lamar.IoC.Instances.FuncResolverDefinition.BuildResolver() at Lamar.IoC.Instances.GeneratedInstance.BuildFuncResolver(Scope scope) at Lamar.IoC.Instances.GeneratedInstance.buildResolver(Scope scope) at Lamar.IoC.Instances.GeneratedInstance.ToResolver(Scope topScope) at Lamar.ServiceGraph.FindResolver(Type serviceType) at Lamar.IoC.Scope.GetInstance(Type serviceType) at Lamar.Container.Microsoft.Extensions.DependencyInjection.ISupportRequiredService.GetRequiredService(Type serviceType) at Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService(IServiceProvider provider, Type serviceType) at Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService[T](IServiceProvider provider) at Lamar.Microsoft.DependencyInjection.WebHostBuilderExtensions.<>c.b3_0(IServiceProvider sp) at Lamar.IoC.Resolvers.SingletonLambdaResolver2.Build(Scope scope) at Lamar.IoC.Resolvers.SingletonResolver1.Resolve(Scope scope) at Lamar.IoC.Instances.LambdaInstance`2.Resolve(Scope scope) at Lamar.IoC.Instances.Instance.QuickResolve(Scope scope) at Lamar.IoC.Instances.ConstructorInstance.<>cDisplayClass18_0.b0(CtorArg x) at System.Linq.Enumerable.SelectArrayIterator2.ToArray() at System.Linq.Enumerable.ToArray[TSource](IEnumerable1 source) at Lamar.IoC.Instances.ConstructorInstance.quickResolve(Scope scope) at Lamar.IoC.Instances.ConstructorInstance.QuickResolve(Scope scope) at Lamar.IoC.Instances.ConstructorInstance.<>cDisplayClass18_0.b0(CtorArg x) at System.Linq.Enumerable.SelectArrayIterator2.ToArray() at System.Linq.Enumerable.ToArray[TSource](IEnumerable1 source) at Lamar.IoC.Instances.ConstructorInstance.quickResolve(Scope scope) at Lamar.IoC.Instances.ConstructorInstance.QuickResolve(Scope scope) at Lamar.IoC.Instances.ConstructorInstance.<>cDisplayClass18_0.b0(CtorArg x) at System.Linq.Enumerable.SelectArrayIterator2.ToArray() at System.Linq.Enumerable.ToArray[TSource](IEnumerable1 source) at Lamar.IoC.Instances.ConstructorInstance.quickResolve(Scope scope) at Lamar.IoC.Instances.ConstructorInstance.<>cDisplayClass15_0.b0(Scope s) at Lamar.ServiceGraph.<>cDisplayClass48_0.b__0(Scope s) at Lamar.IoC.Scope.GetInstance(Type serviceType) at Lamar.Container.Microsoft.Extensions.DependencyInjection.ISupportRequiredService.GetRequiredService(Type serviceType) at Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService(IServiceProvider provider, Type serviceType) at Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService[T](IServiceProvider provider) at Microsoft.Extensions.Hosting.HostBuilder.Build() at RestApi.Host.Program.Main(String[] args) in C:\RestApi.Host\Program.cs:line 16

I would assume that ,WithDefaultConventions() would register and resolve that service, but it's not doing it.

We are using: Lamar v4.0.0 Lamar.Microsoft.DependencyInjection v4.0.2

jeremydmiller commented 4 years ago

@mdelprado-emphasys Dollars to donuts, you've got multiple, incompatible versions of whatever assembly the RestApiHost.Services.AuthService type is in in your system. You're seeing the error with Lamar resolution, but I don't think your problem is caused by Lamar. You might have a diamond dependency issue.

Any time you see a MissingMethodException, it means some bit of code was compiled against an incompatible version of a referenced assembly compared to what is running in the app.

CodingGorilla commented 4 years ago

I would mention that I got this exception when I upgraded to Lamar 4.0.0, but I was also using Jasper v0.9.x. I assumed this was probably just because Jasper hadn't been updated against the latest version of Lamar, but maybe there's a bigger issue?

mdelprado-emphasys commented 4 years ago

@jeremydmiller what do you mean by having multiple versions of the assembly where AuthService is in? AuthService and the Lamar configuration are on the same assembly, so I'm not sure I understand. I actually got rid of the error by creating a new container, but then the application is not able to resolve the type AuthService with the option WithDefaultConventions(), so I don't think that's really working even though I don't get the error.

jeremydmiller commented 4 years ago

@mdelprado-emphasys Like I said, MissingMethodException always means mismatched assemblies. Maybe check your *.assets.json file and see if you can spot where multiple versions of the same assembly are being used?

jeremydmiller commented 4 years ago

No recent activity, I'm closing this.