In .NET core, the generated .deps.json file controls assembly loading - if your dependencies aren't in the .deps.json for your top level application, they will not get loaded unless you start handling AssemblyResolve events and all that stuff.

The situation I have is as follows

.NET Core 6

Class Library Assembly - lets call it 'ClassLib'

Application (exe) - lets call it 'App' - that depends on 'ClassLib' as a project reference

If I use a Nuget package (PackageReference) inside ClassLib then the Nuget package shows up in the generated App.deps.json and everything works. (Newtonsoft.json used as an example of this below)

However, I have several cases where there are legacy assemblies that I wish to reference that are not in Nuget packages. Those can be added as references using the UI (Add COM Reference then 'Browse' to the assembly) or via a <Reference ...> node in the csproj.

When you build 'App', the App.deps.json does not include any sign of the dependencies on the legacy assemblies via ClassLib, just the nuget packages. This means that at runtime, the legacy assembly is not going to get loaded, leading to all sorts of interesting failures...

Details of the situation

ClassLib.csproj contents

<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <TargetFramework>net6.0</TargetFramework>
    <ImplicitUsings>enable</ImplicitUsings>
    <Nullable>enable</Nullable>
  </PropertyGroup>

  <ItemGroup>
    <PackageReference Include="Newtonsoft.Json" Version="13.0.2" />
  </ItemGroup>

  <ItemGroup>
    <Reference Include="Legacy">
      <HintPath>..\path\to\Legacy.dll</HintPath>
      <SpecificVersion>True</SpecificVersion>
    </Reference>
  </ItemGroup>

</Project>

App.csproj contains

<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>net6.0</TargetFramework>
    <ImplicitUsings>enable</ImplicitUsings>
    <Nullable>enable</Nullable>
  </PropertyGroup>

  <ItemGroup>
    <ProjectReference Include="..\ClassLib\ClassLib.csproj" />
  </ItemGroup>

</Project>

Generated App.deps.json shows the dependency of ClassLib on NewtonSoft.Json (imported as Nuget) but not on Legacy.dll

      "ClassLib/1.0.0": {
        "dependencies": {
          "Newtonsoft.Json": "13.0.2"
        },
        "runtime": {
          "ClassLib.dll": {}
        }
      }

I have tried various combinations of options in the node such as CopyLocal/Private etc with no change to the outcome in terms of the generated App.deps.json

I can make things work if I pack Legacy.dll into a nuget package, but to be honest I have a number of legacy dlls to deal with and making each into a nuget package (they come from various sources and may be updated separately) seems rather a 'sledgehammer to crack a nut' solution.

so...

Is there a way that I can persuade the build system to treat the old-fashioned assembly reference in the same way as the package reference and propagate the dependencies up to higher level projects? Failing that, is there a way that you can customize the build process to inject dependencies into the .deps.json file at build time? (hey, a different sort of dependency injection!) Or am I stuck making nuget packages or hacking around in AssemblyResolve events?

0

There are 0 best solutions below