Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CLI Breaks when run against netstandard 2.1 assemblies #1160

Closed
scmccart opened this issue Feb 3, 2020 · 6 comments
Closed

CLI Breaks when run against netstandard 2.1 assemblies #1160

scmccart opened this issue Feb 3, 2020 · 6 comments

Comments

@scmccart
Copy link

scmccart commented Feb 3, 2020

When running the CLI against a migration assembly that targets netstandard2.1 it fails with the message below. We do use "dotnet publish" to create the migration assembly.

System.IO.FileNotFoundException: Could not load file or assembly 'netstandard, Version=2.1.0.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51'. The system cannot find the file specified.

@jzabroski
Copy link
Collaborator

Can you please provide a repro project? These kinds of assembly location issues can be a time sink/nightmare to reproduce without a repro project. There are simply too many knobs to turn associated with assembly location.

Note: Using "dotnet publish" by itself to create the migration assembly is not magical. It's the .deps.json file that is created alongside your assembly that is somewhat magical, as it tells the .NET Runtime about your executable's dependencies.

When running the CLI

Are you referring to FluentMigrator.DotNet.Cli, or the In Process Runner? If the former, please see #1016 - we suggest using an In-Process Runner when you have this problem.

@szyb
Copy link

szyb commented Jun 15, 2020

I have the same problem, but I couldn't reproduce it with small example project. All I have is a stack trace, maybe this will tell something to you

Unhandled Exception: System.IO.FileNotFoundException: Could not load file or assembly 'netstandard, Version=2.1.0.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51'. Nie można odnaleźć określonego pliku.
   at System.Reflection.RuntimeAssembly.GetExportedTypes(RuntimeAssembly assembly, ObjectHandleOnStack retTypes)
   at System.Reflection.RuntimeAssembly.GetExportedTypes()
   at System.Linq.Enumerable.SelectManySingleSelectorIterator`2.MoveNext()
   at System.Linq.Enumerable.TryGetFirst[TSource](IEnumerable`1 source, Func`2 predicate, Boolean& found)
   at FluentMigrator.Runner.Initialization.AssemblySourceMigrationRunnerConventionsAccessor.<>c__DisplayClass1_0.<.ctor>b__0() in d:\a\1\s\src\FluentMigrator.Runner.Core\Initialization\AssemblySourceMigrationRunnerConventionsAccessor.cs:line 50
   at System.Lazy`1.ViaFactory(LazyThreadSafetyMode mode)
   at System.Lazy`1.ExecutionAndPublication(LazyHelper executionAndPublication, Boolean useDefaultConstructor)
   at System.Lazy`1.CreateValue()
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitScoped(ScopedCallSite scopedCallSite, ServiceProvider provider)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitConstructor(ConstructorCallSite constructorCallSite, ServiceProvider provider)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitScoped(ScopedCallSite scopedCallSite, ServiceProvider provider)
   at Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService(IServiceProvider provider, Type serviceType)
   at Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService[T](IServiceProvider provider)
   at Microsoft.Extensions.DependencyInjection.FluentMigratorServiceCollectionExtensions.<>c.<AddFluentMigratorCore>b__0_2(IServiceProvider sp) in d:\a\1\s\src\FluentMigrator.Runner\FluentMigratorServiceCollectionExtensions.cs:line 92
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitScoped(ScopedCallSite scopedCallSite, ServiceProvider provider)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitConstructor(ConstructorCallSite constructorCallSite, ServiceProvider provider)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitScoped(ScopedCallSite scopedCallSite, ServiceProvider provider)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitConstructor(ConstructorCallSite constructorCallSite, ServiceProvider provider)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitScoped(ScopedCallSite scopedCallSite, ServiceProvider provider)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitConstructor(ConstructorCallSite constructorCallSite, ServiceProvider provider)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitScoped(ScopedCallSite scopedCallSite, ServiceProvider provider)
   at Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService(IServiceProvider provider, Type serviceType)
   at Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService[T](IServiceProvider provider)
   at FluentMigrator.Runner.Initialization.TaskExecutor.RunnerScope..ctor(TaskExecutor executor) in d:\a\1\s\src\FluentMigrator.Runner\Initialization\TaskExecutor.cs:line 253
   at FluentMigrator.Runner.Initialization.TaskExecutor.Execute() in d:\a\1\s\src\FluentMigrator.Runner\Initialization\TaskExecutor.cs:line 157
   at FluentMigrator.DotNet.Cli.Commands.BaseCommand.ExecuteMigrations(MigratorOptions options, IConsole console) in d:\a\1\s\src\FluentMigrator.DotNet.Cli\Commands\BaseCommand.cs:line 32
   at FluentMigrator.DotNet.Cli.Commands.Migrate.OnExecute(IConsole console) in d:\a\1\s\src\FluentMigrator.DotNet.Cli\Commands\Migrate.cs:line 31
--- End of stack trace from previous location where exception was thrown ---
   at McMaster.Extensions.CommandLineUtils.Conventions.ExecuteMethodConvention.Invoke(MethodInfo method, Object instance, Object[] arguments)
   at McMaster.Extensions.CommandLineUtils.Conventions.ExecuteMethodConvention.OnExecute(ConventionContext context)
   at McMaster.Extensions.CommandLineUtils.Conventions.ExecuteMethodConvention.<>c__DisplayClass0_0.<<Apply>b__0>d.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at McMaster.Extensions.CommandLineUtils.CommandLineApplication.<>c__DisplayClass142_0.<OnExecute>b__0()
   at McMaster.Extensions.CommandLineUtils.CommandLineApplication.Execute[TApp](CommandLineContext context)
   at McMaster.Extensions.CommandLineUtils.CommandLineApplication.Execute[TApp](IConsole console, String[] args)
   at FluentMigrator.DotNet.Cli.Program.Main(String[] args) in d:\a\1\s\src\FluentMigrator.DotNet.Cli\Program.cs:line 35

I'm running migrations from batch

dotnet publish
cd bin\debug\netstandard2.1\publish
dotnet fm migrate --strip:false -t Development -p postgres -c "[connection_string]" -a migrations.dll

@jzabroski
Copy link
Collaborator

@szyb Please see my reply directly above your comment.

When running the CLI

Are you referring to FluentMigrator.DotNet.Cli, or the In Process Runner? If the former, please see #1016 - we suggest using an In-Process Runner when you have this problem.

A more permanent fix is coming in #1178

The most common way I've run into assembly link-load problem is by referencing System.ComponentModel.Annotations nuget package. What System.* assemblies are you referencing in your erroring project?

@szyb
Copy link

szyb commented Jun 16, 2020

In fact, I have reference to System.ComponentModel.Annotations, however adding it to my small trying-to-be-repro project didn't show any issues with that.
For me, now it is better to temporarily downgrade project to net standard 2.0 as all deploy scripts and team members uses FluentMigrator.DotNet.Cli runner and we would like to keep it that way.
I'm looking forward to permanent fix. Good luck!

@jzabroski
Copy link
Collaborator

System.ComponentModel.Annotations is the worst because its OOB and, in my opinion, packaged incorrectly. If you search the dotnet org GitHub, you will find me complaining about this.

The problem is the net472 assembly uses a different z in x.y.z version number. This creates a dependency diamond. It is not FluentMigrator's fault that Microsoft packaged System.ComponentModel.Annotations in a way that makes netstandard2.0 unusable for dynamically loaded assemblies, and the ONLY fix for this packaging issue is to use an In-Process Runner. However, the issue I mentioned tries to solve all other problems. I believe .NET 5.0 will not change the 'z' field in the version number across runtimes going forward, after I raised the problems with it, but I have not confirmed.

@jzabroski
Copy link
Collaborator

Also, note, just adding a package won't necessarily cause problems. It has to be linked to the runtime assembly fluent migrator is walking.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants