Aspnetcore: Cannot find compilation library location for package "XYZ"

Created on 14 Aug 2017  路  11Comments  路  Source: dotnet/aspnetcore

.NET Command Line Tools (2.0.0)

Product Information:
 Version:            2.0.0
 Commit SHA-1 hash:  cdcd1928c9

Runtime Environment:
 OS Name:     Mac OS X
 OS Version:  10.12
 OS Platform: Darwin
 RID:         osx.10.12-x64
 Base Path:   /usr/local/share/dotnet/sdk/2.0.0/

Microsoft .NET Core Shared Framework Host

  Version  : 2.0.0
  Build    : e8b8861ac7faf042c87a5c2f9f2d04c98b69f28d

MyApp uses a full .net library:

MyApp.csproj:

...
  <PropertyGroup>
    <TargetFramework>netcoreapp2.0</TargetFramework>
    <DebugType>portable</DebugType>
    <AssemblyName>ihs</AssemblyName>
    <OutputType>Exe</OutputType>
    <PackageId>ihs</PackageId>
    <AssetTargetFallback>$(AssetTargetFallback);net452</AssetTargetFallback>
    <GenerateAssemblyInfo>false</GenerateAssemblyInfo>
  </PropertyGroup>
...
 <ItemGroup>
    <Reference Include="X.Y.dll">
      <HintPath>../ThirdParty/X.Y.dll</HintPath>
    </Reference>
  </ItemGroup>

Just upgraded from .net core 2 preview 2 to .net core 2 final and get this error message

  Cannot find compilation library location for package 'X.Y'
     at Microsoft.Extensions.DependencyModel.CompilationLibrary.ResolveReferencePaths(ICompilationAssemblyResolver resolver, List`1 assemblies)
     at Microsoft.Extensions.DependencyModel.CompilationLibrary.ResolveReferencePaths()
     at Microsoft.AspNetCore.Mvc.ApplicationParts.AssemblyPart.<>c.<GetReferencePaths>b__8_0(CompilationLibrary library)
     at System.Linq.Enumerable.SelectManySingleSelectorIterator`2.MoveNext()
     at Microsoft.AspNetCore.Mvc.Razor.Compilation.MetadataReferenceFeatureProvider.PopulateFeature(IEnumerable`1 parts, MetadataReferenceFeature feature)
     at Microsoft.AspNetCore.Mvc.ApplicationParts.ApplicationPartManager.PopulateFeature[TFeature](TFeature feature)
     at Microsoft.AspNetCore.Mvc.Razor.Internal.DefaultRazorReferenceManager.GetCompilationReferences()
     at System.Threading.LazyInitializer.EnsureInitializedCore[T](T& target, Boolean& initialized, Object& syncLock, Func`1 valueFactory)
     at Microsoft.AspNetCore.Mvc.Razor.Internal.DefaultRazorReferenceManager.get_CompilationReferences()
     at Microsoft.AspNetCore.Mvc.Razor.Internal.CSharpCompiler.CreateCompilation(String assemblyName)
     at Microsoft.AspNetCore.Mvc.Razor.ViewCompilation.Internal.PrecompileRunCommand.CompileViews(ViewCompilationInfo[] results, String assemblyname)
     at Microsoft.AspNetCore.Mvc.Razor.ViewCompilation.Internal.PrecompileRunCommand.Execute()
     at Microsoft.Extensions.CommandLineUtils.CommandLineApplication.Execute(String[] args)
     at Microsoft.AspNetCore.Mvc.Razor.ViewCompilation.Internal.PrecompilationApplication.Execute(String[] args)
/usr/local/share/dotnet/sdk/NuGetFallbackFolder/microsoft.aspnetcore.mvc.razor.viewcompilation/2.0.0/build/netstandard2.0/Microsoft.AspNetCore.Mvc.Razor.ViewCompilation.targets(60,5): error MSB3073: The command ""/usr/local/share/dotnet/dotnet" exec --runtimeconfig "/Users/jdelfour/code/UCP/UDL-API/myapp/src/bin/Release/netcoreapp2.0/myapp.runtimeconfig.json" --depsfile "/Users/jdelfour/code/UCP/UDL-API/myapp/src/bin/Release/netcoreapp2.0/myapp.deps.json" "/usr/local/share/dotnet/sdk/NuGetFallbackFolder/microsoft.aspnetcore.mvc.razor.viewcompilation/2.0.0/build/netstandard2.0/Microsoft.AspNetCore.Mvc.Razor.ViewCompilation.dll" @"obj/Release/netcoreapp2.0/microsoft.aspnetcore.mvc.razor.viewcompilation.rsp"" exited with code 1. [/Users/jdelfour/code/UCP/UDL-API/myapp/src/myapp.csproj]

Adding the following to my dotnet publish -c release does the trick:
/p:MvcRazorCompileOnPublish=false

This was not required in .net core 2 preview 2 and this worked fine as i do not have any razor view
But why does it fail now?

seems similar to: https://github.com/aspnet/Home/issues/2105

Duplicate

Most helpful comment

@Jonathan34 looks like you ran in to https://github.com/dotnet/core-setup/issues/2981. The issue seems to be that DependencyContext which is what Mvc uses to discover compile time references for views doesn't have a resolver for referenced binaries. The work item seems to have an (IMO, a super hacky) work around which you might be able to use. The other alternative would be to modify the pieces in Mvc that use DependencyContext to locate reference assembly paths:

```C#
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection.PortableExecutable;
using Microsoft.AspNetCore.Mvc.ApplicationParts;
using Microsoft.CodeAnalysis;
using Microsoft.Extensions.DependencyModel;

namespace Microsoft.AspNetCore.Mvc.Razor.Compilation
{
public class ReferencesMetadataReferenceFeatureProvider : IApplicationFeatureProvider
{
public void PopulateFeature(IEnumerable parts, MetadataReferenceFeature feature)
{
var libraryPaths = new HashSet(StringComparer.OrdinalIgnoreCase);
foreach (var assemblyPart in parts.OfType())
{
var dependencyContext = DependencyContext.Load(assemblyPart.Assembly);
if (dependencyContext != null)
{
foreach (var library in dependencyContext.CompileLibraries)
{
if (string.Equals("reference", library.Type, StringComparison.OrdinalIgnoreCase))
{
foreach (var libraryAssembly in library.Assemblies)
{
libraryPaths.Add(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, libraryAssembly));
}
}
else
{
foreach (var path in library.ResolveReferencePaths())
{
libraryPaths.Add(path);
}
}
}
}
else
{
libraryPaths.Add(assemblyPart.Assembly.Location);
}
}

        foreach (var path in libraryPaths)
        {
            feature.MetadataReferences.Add(CreateMetadataReference(path));
        }
    }

    private static MetadataReference CreateMetadataReference(string path)
    {
        using (var stream = File.OpenRead(path))
        {
            var moduleMetadata = ModuleMetadata.CreateFromStream(stream, PEStreamOptions.PrefetchMetadata);
            var assemblyMetadata = AssemblyMetadata.Create(moduleMetadata);

            return assemblyMetadata.GetReference(filePath: path);
        }
    }
}

}

And in your Startup:

```C#
services.AddMvc()
    .ConfigureApplicationPartManager(manager =>
    {
        var oldMetadataReferenceFeatureProvider = manager.FeatureProviders.First(f => f is MetadataReferenceFeatureProvider);
        manager.FeatureProviders.Remove(oldMetadataReferenceFeatureProvider);
        manager.FeatureProviders.Add(new ReferencesMetadataReferenceFeatureProvider());
    });

cc @tuespetre since this might be a slightly better solution to modifying fields using private reflection

All 11 comments

@Jonathan34 looks like you ran in to https://github.com/dotnet/core-setup/issues/2981. The issue seems to be that DependencyContext which is what Mvc uses to discover compile time references for views doesn't have a resolver for referenced binaries. The work item seems to have an (IMO, a super hacky) work around which you might be able to use. The other alternative would be to modify the pieces in Mvc that use DependencyContext to locate reference assembly paths:

```C#
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection.PortableExecutable;
using Microsoft.AspNetCore.Mvc.ApplicationParts;
using Microsoft.CodeAnalysis;
using Microsoft.Extensions.DependencyModel;

namespace Microsoft.AspNetCore.Mvc.Razor.Compilation
{
public class ReferencesMetadataReferenceFeatureProvider : IApplicationFeatureProvider
{
public void PopulateFeature(IEnumerable parts, MetadataReferenceFeature feature)
{
var libraryPaths = new HashSet(StringComparer.OrdinalIgnoreCase);
foreach (var assemblyPart in parts.OfType())
{
var dependencyContext = DependencyContext.Load(assemblyPart.Assembly);
if (dependencyContext != null)
{
foreach (var library in dependencyContext.CompileLibraries)
{
if (string.Equals("reference", library.Type, StringComparison.OrdinalIgnoreCase))
{
foreach (var libraryAssembly in library.Assemblies)
{
libraryPaths.Add(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, libraryAssembly));
}
}
else
{
foreach (var path in library.ResolveReferencePaths())
{
libraryPaths.Add(path);
}
}
}
}
else
{
libraryPaths.Add(assemblyPart.Assembly.Location);
}
}

        foreach (var path in libraryPaths)
        {
            feature.MetadataReferences.Add(CreateMetadataReference(path));
        }
    }

    private static MetadataReference CreateMetadataReference(string path)
    {
        using (var stream = File.OpenRead(path))
        {
            var moduleMetadata = ModuleMetadata.CreateFromStream(stream, PEStreamOptions.PrefetchMetadata);
            var assemblyMetadata = AssemblyMetadata.Create(moduleMetadata);

            return assemblyMetadata.GetReference(filePath: path);
        }
    }
}

}

And in your Startup:

```C#
services.AddMvc()
    .ConfigureApplicationPartManager(manager =>
    {
        var oldMetadataReferenceFeatureProvider = manager.FeatureProviders.First(f => f is MetadataReferenceFeatureProvider);
        manager.FeatureProviders.Remove(oldMetadataReferenceFeatureProvider);
        manager.FeatureProviders.Add(new ReferencesMetadataReferenceFeatureProvider());
    });

cc @tuespetre since this might be a slightly better solution to modifying fields using private reflection

@Eilon - a couple of folks have run in to this (https://github.com/dotnet/core-setup/issues/2981, https://github.com/dotnet/core-setup/issues/2307). This would be a good candidate for 2.0.1.

I worked around it with /p:MvcRazorCompileOnPublish=false. Is it not recommended to do that? I do not have any view...
When is 2.0.1 due?

@Jonathan34 that should be fine. The template for API projects includes a <MvcRazorCompileOnPublish>false</MvcRazorCompileOnPublish> so you're effectively doing the same.

I'm running into a similar issue with an ASP.NET Core 1.1 project after upgrading to VS2017.3 and the .NET Core 2.0 SDK.

I get this error

System.InvalidOperationException occurred
  HResult=0x80131509
  Message=Can not find assembly file Microsoft.CSharp.dll at 'C:\Projects\Offero\src\Offero.Web\bin\Debug\net462\refs,C:\Projects\Offero\src\Offero.Web\bin\Debug\net462\'
  Source=Microsoft.Extensions.DependencyModel
  StackTrace:
   at Microsoft.Extensions.DependencyModel.Resolution.AppBaseCompilationAssemblyResolver.TryResolveAssemblyPaths(CompilationLibrary library, List`1 assemblies)
   at Microsoft.Extensions.DependencyModel.Resolution.CompositeCompilationAssemblyResolver.TryResolveAssemblyPaths(CompilationLibrary library, List`1 assemblies)
   at Microsoft.Extensions.DependencyModel.CompilationLibrary.ResolveReferencePaths()
   at Microsoft.AspNetCore.Mvc.ApplicationParts.AssemblyPart.<>c.<GetReferencePaths>b__8_0(CompilationLibrary library)
   at System.Linq.Enumerable.<SelectManyIterator>d__16`2.MoveNext()
   at Microsoft.AspNetCore.Mvc.Razor.Compilation.MetadataReferenceFeatureProvider.PopulateFeature(IEnumerable`1 parts, MetadataReferenceFeature feature)
   at Microsoft.AspNetCore.Mvc.ApplicationParts.ApplicationPartManager.PopulateFeature[TFeature](TFeature feature)
   at Microsoft.AspNetCore.Mvc.Razor.Internal.RazorReferenceManager.GetCompilationReferences()
   at System.Threading.LazyInitializer.EnsureInitializedCore[T](T& target, Boolean& initialized, Object& syncLock, Func`1 valueFactory)
   at Microsoft.AspNetCore.Mvc.Razor.Internal.RazorReferenceManager.get_CompilationReferences()
   at Microsoft.AspNetCore.Mvc.Razor.Internal.DefaultRoslynCompilationService.CreateCompilation(String compilationContent, String assemblyName)
   at Microsoft.AspNetCore.Mvc.Razor.Internal.DefaultRoslynCompilationService.Compile(RelativeFileInfo fileInfo, String compilationContent)
   at Microsoft.AspNetCore.Mvc.Razor.Internal.RazorCompilationService.Compile(RelativeFileInfo file)
   at Microsoft.AspNetCore.Mvc.Razor.Internal.CompilerCache.CreateCacheEntry(String relativePath, String normalizedPath, Func`2 compile)
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at Microsoft.AspNetCore.Mvc.Razor.Internal.CompilerCache.GetOrAdd(String relativePath, Func`2 compile)
   at Microsoft.AspNetCore.Mvc.Razor.Internal.DefaultRazorPageFactoryProvider.CreateFactory(String relativePath)
   at Microsoft.AspNetCore.Mvc.Razor.RazorViewEngine.CreateCacheResult(HashSet`1 expirationTokens, String relativePath, Boolean isMainPage)
   at Microsoft.AspNetCore.Mvc.Razor.RazorViewEngine.OnCacheMiss(ViewLocationExpanderContext expanderContext, ViewLocationCacheKey cacheKey)
   at Microsoft.AspNetCore.Mvc.Razor.RazorViewEngine.LocatePageFromViewLocations(ActionContext actionContext, String pageName, Boolean isMainPage)
   at Microsoft.AspNetCore.Mvc.Razor.RazorViewEngine.FindView(ActionContext context, String viewName, Boolean isMainPage)

This seems to happen if I have a net462 web app that references a netstandard library. If I remove the reference everything works fine again.

Also, downgrading back to the .NET 1.1 SDK works as well.

Could this be the same error or is this something different?

I built a small sample just to make sure it wasn't something else in our code that was causing this. It's at https://github.com/squareitechnologies/VS2017Issue if that helps

@pranavkm how dare you call my hack a hack!

JK, thanks for the improved workaround. I like it much better.

@pranavkm should this bug be closed as a dup of https://github.com/dotnet/core-setup/issues/2981 ?

Yup.

Getting the same error w a custom Asp.Net Core 2.0 library that uses Reflection and Linq (no Razor). Works fine if I include the project in the solution, crashes w just a ref to the dll. App will be distributed to 3rd parties so can't distribute the project.

@alex-brambila since this is a closed issue and your scenario doesn't pertain to Razor, I'd recommend starting a new work item with more details.

Was this page helpful?
0 / 5 - 0 ratings