How to find missing runtime dependencies in .NET?

How to Find Missing Runtime Dependencies in .NET

Summary

TargetInvocationException errors with inner FileNotFoundException indicate missing runtime assemblies required by your .NET Framework 4.7.2 application. Unlike compilation dependencies, these are detected at runtime when the CLR fails to locate referenced assemblies or their dependencies. Standard tools like Process Explorer only show loaded modules, not failed bindings, making invisible dependencies difficult to diagnose.

Root Cause

The failure occurs due to:

  • Inaccurate assembly resolution paths (directories examined by CLR exclude the dependency’s location)
  • Version mismatch between referenced and available assemblies
  • Missing transitive dependencies (assemblies required by your assembly’s dependencies)
  • Native image issues (like mscorlib.ni.dll being loaded instead of base mscorlib.dll)
  • Deployment gaps where dependencies exist on dev machines but not in target environments

Why This Happens in Real Systems

These issues emerge due to:

  • Environment inconsistency between development, testing, and production machines
  • Compile-time vs. runtime resolution differences (successful compilation doesn’t guarantee runtime presence)
  • Implicit dependency chains that aren’t apparent in Visual Studio references
  • Third-party package quirks (NuGet packages might intangible dependencies)
  • Global Assembly Cache (GAC) assumptions where dev machines have assemblies that target machines lack

Real-World Impact

Unresolved dependencies cause:

  • Application crashes (System.Reflection.TargetInvocationException)
  • Partial functionality failure when only specific features are affected
  • Deployment headaches due to inconsistent environment behaviors (“works on my machine”)
  • Support overhead for troubleshooting machine-specific
    Note: While Fusion Log٢ is powerful, alternatives include:
    dotnet-trace + dotnet-dump for .NET Core diagnostics
    – Static analyzers like Fody.Costura for embedding dependencies

Why Juniors Miss It

Junior engineers often struggle because:

  • Tooling blind spots: Relying solely on Process Explorer instead of assembly logging tools
  • False assumptions: Assuming compile-time dependencies guarantee runtime availability
  • Environment naïveté: Not validating dependencies across all target environments
  • Exception oversimplification: Treating FileNotFoundException as literal rather than probing binding failure
  • Transitive neglect: Overlooking dependencies of dependencies in the reference chain

Key takeaway: Always validate assembly binding behavior in lowest-common-denominator environments using CLR diagnostic tools.