dotnet / msbuild

The Microsoft Build Engine (MSBuild) is the build platform for .NET and Visual Studio.
https://docs.microsoft.com/visualstudio/msbuild/msbuild
MIT License
5.23k stars 1.35k forks source link

ResolveAssemblyReference is slow on .NET Core with many references #2015

Open rainersigwald opened 7 years ago

rainersigwald commented 7 years ago

ResolveAssemblyReferences runs unconditionally even on incremental builds (because the user may have installed a targeting pack or, for full-framework scenarios, GACed an assembly). This makes it performance-sensitive.

With the advent of .NET Core micro-assemblies, it has become common to pass many, many references to RAR. This exacerbates performance problems.

@rynowak was kind enough to run a profiler to see this: image

rainersigwald commented 7 years ago

One thing of note: MSBuild only calls that AssemblyName constructor because AssemblyName.Clone() isn't available in .NET Standard 1.x. One possible improvement here would be to move to .NET Core 2.0.

rynowak commented 7 years ago

To add a little more detail we really have a project that's taking this long to build (referring to the 95sec spent in UnifyAssemblyNameVersions).

You may want to check out https://github.com/aspnet/Mvc/tree/dev/test/Microsoft.AspNetCore.Mvc.FunctionalTests in general as example of a really complicated dotnet core package that's updated to the bleeding edge.

eerhardt commented 7 years ago

There's an ask from the ASP.NET team to not even run ResolveAssemblyReference in some cases. See https://github.com/dotnet/sdk/issues/1193

ericstj commented 7 years ago

I think you should look at a couple options:

  1. Caching immutable data (like metadata about a file inside a nuget package / targeting pack) to avoid recalculation from multiple processes / projects / rebuilds.
  2. Identifying a fast path to skip RAR entirely and populate its outputs from a cache file in OBJ.

I think #2 is doable if we look at the right set of inputs/outputs and potentially change AssemblySearchPaths for some project types.

rainersigwald commented 7 years ago

There is a cache in RAR but we can't use it in Core because it depends on BinarySerialization which isn't accessible to us.

I'm fairly hesitant to build any assumptions about nuget immutability into RAR.

DamianEdwards commented 7 years ago

Isn't binary serialization available in netcoreapp2.0 now, as part of netstandard2.0?

rainersigwald commented 7 years ago

@DamianEdwards Yes, but we're not targeting that. We'd like to but it's a lot of work and we can't do it for 15.3.

DamianEdwards commented 7 years ago

@rainersigwald can you not light-up on it in the same way you did for the change above? Or is not really factored to enable that easily right now?

rainersigwald commented 7 years ago

@DamianEdwards I don't think so, because binary serialization requires source attributes, which can't be discovered via reflection.

kieranmo commented 7 years ago

What other serialization options do we have?

rainersigwald commented 7 years ago

I'm going to spend tomorrow on some prototyping and profiling on this.

DamianEdwards commented 7 years ago

@rainersigwald thanks

rainersigwald commented 7 years ago

@DamianEdwards what's the best scenario to hammer on? A dotnet new web project with sdk 2, and incremental dotnet builds? On my machine RAR doesn't seem like a significant part of that (1 ms of the 1 s build) while NuGet operations take the time:

        9 ms  CheckForImplicitPackageReferenceOverrides   1 calls
       20 ms  ProduceContentAssets                       1 calls
       99 ms  GenerateRuntimeConfigurationFiles          1 calls
      149 ms  ResolvePackageFileConflicts                1 calls
      239 ms  ResolvePackageDependencies                 1 calls
DamianEdwards commented 7 years ago

@rainersigwald try dotnet new mvc. Here's the result on my machine (all from the CLI using dotnet build):

1st build

   9 ms  CoreGenerateAssemblyInfo                   1 calls
  32 ms  CheckForImplicitPackageReferenceOverrides   1 call
  32 ms  _CopyOutOfDateSourceItemsToOutputDirectory   1 cal
  33 ms  RunProduceContentAssets                    1 calls
  47 ms  _ComputeLockFileReferences                 1 calls
  67 ms  GenerateBuildRuntimeConfigurationFiles     1 calls
  81 ms  ResolveLockFileReferences                  1 calls
 108 ms  _ComputeLockFileCopyLocal                  1 calls
 123 ms  GenerateBuildDependencyFile                1 calls
 172 ms  RunResolvePackageDependencies              1 calls
 246 ms  _HandlePackageFileConflicts                1 calls
 905 ms  ResolveAssemblyReferences                  1 calls
1388 ms  CoreCompile                                1 calls

2nd build

  8 ms  CoreCompile                                1 calls
 11 ms  CheckForImplicitPackageReferenceOverrides   1 calls
 33 ms  RunProduceContentAssets                    1 calls
 52 ms  _ComputeLockFileReferences                 1 calls
 69 ms  GenerateBuildRuntimeConfigurationFiles     1 calls
 80 ms  ResolveLockFileReferences                  1 calls
108 ms  _ComputeLockFileCopyLocal                  1 calls
147 ms  _HandlePackageFileConflicts                1 calls
186 ms  RunResolvePackageDependencies              1 calls
960 ms  ResolveAssemblyReferences                  1 calls

3rd build

  8 ms  CoreCompile                                1 calls
 12 ms  CheckForImplicitPackageReferenceOverrides   1 calls
 34 ms  RunProduceContentAssets                    1 calls
 46 ms  _ComputeLockFileReferences                 1 calls
 66 ms  GenerateBuildRuntimeConfigurationFiles     1 calls
 79 ms  ResolveLockFileReferences                  1 calls
119 ms  _ComputeLockFileCopyLocal                  1 calls
140 ms  _HandlePackageFileConflicts                1 calls
182 ms  RunResolvePackageDependencies              1 calls
950 ms  ResolveAssemblyReferences                  1 calls
rynowak commented 7 years ago

Or use this project if you want a really fun one 😆

https://github.com/aspnet/Mvc/tree/dev/test/Microsoft.AspNetCore.Mvc.FunctionalTests

rainersigwald commented 7 years ago

Here's what I've figured out so far:

There are a couple of options to shorten this:

I spoke to a source who was involved with RAR in the past (you can't escape if you're still in DevDiv, but I can keep your name out of the press!) who thought that the best option might be to teach the NuGet-resolution targets to emit directly to the items that are RAR outputs (like @(ReferencePath)), instead of resolving from NuGet assets file -> items pointing to paths on disk -> RAR -> different set of items pointing to paths on disk.

RAR does basically three things, none of which are super interesting for NuGet references:

We can't eliminate RAR altogether, because when targeting a full framework TFM you can use references that don't come from NuGet (like <Reference Include="System.Configuration" /> or direct reference to a path on disk). But we could filter the list to elide packages that come from NuGet.

I prototyped this with an injected task:

<Target Name="AdjustRAR" BeforeTargets="ResolveAssemblyReferences" Condition="'$(AdjustRAR)' != 'false'">
  <ItemGroup>
    <ReferencePath Include="@(Reference)" Condition="'%(NuGetSourceType)' == 'Package'" />
    <Reference Remove="@(Reference)"  Condition="'%(NuGetSourceType)' == 'Package'" />
  </ItemGroup>
</Target>

For an MVC template project, that completely eliminates RAR:

        9 ms  CoreCompile                                1 calls
       10 ms  AdjustRAR                                  1 calls
       10 ms  _CheckForUnsupportedTargetFramework        1 calls
       18 ms  CheckForImplicitPackageReferenceOverrides   1 calls
       45 ms  FindReferenceAssembliesForReferences       1 calls
       45 ms  RunProduceContentAssets                    1 calls
       65 ms  _ComputeLockFileReferences                 1 calls
       85 ms  GenerateBuildRuntimeConfigurationFiles     1 calls
      128 ms  ResolveLockFileReferences                  1 calls
      155 ms  _ComputeLockFileCopyLocal                  1 calls
      203 ms  _HandlePackageFileConflicts                1 calls
      267 ms  RunResolvePackageDependencies              1 calls

Ok, so great. What are the risks here? We need to sync with the SDK and NuGet teams about:

DamianEdwards commented 7 years ago

@rainersigwald great info. That number of assemblies is much higher than expected (by about 67%). Could you share the list?

DamianEdwards commented 7 years ago

Also, you say:

We can't eliminate RAR altogether, because when targeting a full framework TFM you can use references that don't come from NuGet (like or direct reference to a path on disk). But we could filter the list to elide packages that come from NuGet.

Could we eliminate it in the cases the project is not targeting a full framework TFM then?

rainersigwald commented 7 years ago

Could we eliminate it in the cases the project is not targeting a full framework TFM then?

What I'm hoping is that we can run it only for references that don't come in via NuGet. In the common non-full-framework-targeting case, then, it won't run at all--that's what I see with my target from above.

ericstj commented 7 years ago

You need to run it for full framework on the nuget assemblies as well. It'll find version conflicts and emit bindingRedirects.

rainersigwald commented 7 years ago

@DamianEdwards

Could you share the list?

RAR outputs of `dotnet new mvc` ``` C:\Users\raines\.dotnet\NuGetFallbackFolder\microsoft.aspnetcore.antiforgery\2.0.0-preview1-final\lib\netcoreapp2.0\Microsoft.AspNetCore.Antiforgery.dll C:\Users\raines\.dotnet\NuGetFallbackFolder\microsoft.aspnetcore.authentication.abstractions\2.0.0-preview1-final\lib\netcoreapp2.0\Microsoft.AspNetCore.Authentication.Abstractions.dll C:\Users\raines\.dotnet\NuGetFallbackFolder\microsoft.aspnetcore.authentication.cookies\2.0.0-preview1-final\lib\netcoreapp2.0\Microsoft.AspNetCore.Authentication.Cookies.dll C:\Users\raines\.dotnet\NuGetFallbackFolder\microsoft.aspnetcore.authentication.core\2.0.0-preview1-final\lib\netcoreapp2.0\Microsoft.AspNetCore.Authentication.Core.dll C:\Users\raines\.dotnet\NuGetFallbackFolder\microsoft.aspnetcore.authentication\2.0.0-preview1-final\lib\netcoreapp2.0\Microsoft.AspNetCore.Authentication.dll C:\Users\raines\.dotnet\NuGetFallbackFolder\microsoft.aspnetcore.authentication.facebook\2.0.0-preview1-final\lib\netcoreapp2.0\Microsoft.AspNetCore.Authentication.Facebook.dll C:\Users\raines\.dotnet\NuGetFallbackFolder\microsoft.aspnetcore.authentication.google\2.0.0-preview1-final\lib\netcoreapp2.0\Microsoft.AspNetCore.Authentication.Google.dll C:\Users\raines\.dotnet\NuGetFallbackFolder\microsoft.aspnetcore.authentication.jwtbearer\2.0.0-preview1-final\lib\netcoreapp2.0\Microsoft.AspNetCore.Authentication.JwtBearer.dll C:\Users\raines\.dotnet\NuGetFallbackFolder\microsoft.aspnetcore.authentication.microsoftaccount\2.0.0-preview1-final\lib\netcoreapp2.0\Microsoft.AspNetCore.Authentication.MicrosoftAccount.dll C:\Users\raines\.dotnet\NuGetFallbackFolder\microsoft.aspnetcore.authentication.oauth\2.0.0-preview1-final\lib\netcoreapp2.0\Microsoft.AspNetCore.Authentication.OAuth.dll C:\Users\raines\.dotnet\NuGetFallbackFolder\microsoft.aspnetcore.authentication.openidconnect\2.0.0-preview1-final\lib\netcoreapp2.0\Microsoft.AspNetCore.Authentication.OpenIdConnect.dll C:\Users\raines\.dotnet\NuGetFallbackFolder\microsoft.aspnetcore.authentication.twitter\2.0.0-preview1-final\lib\netcoreapp2.0\Microsoft.AspNetCore.Authentication.Twitter.dll C:\Users\raines\.dotnet\NuGetFallbackFolder\microsoft.aspnetcore.authorization\2.0.0-preview1-final\lib\netcoreapp2.0\Microsoft.AspNetCore.Authorization.dll C:\Users\raines\.dotnet\NuGetFallbackFolder\microsoft.aspnetcore.cookiepolicy\2.0.0-preview1-final\lib\netcoreapp2.0\Microsoft.AspNetCore.CookiePolicy.dll C:\Users\raines\.dotnet\NuGetFallbackFolder\microsoft.aspnetcore.cors\2.0.0-preview1-final\lib\netcoreapp2.0\Microsoft.AspNetCore.Cors.dll C:\Users\raines\.dotnet\NuGetFallbackFolder\microsoft.aspnetcore.cryptography.internal\2.0.0-preview1-final\lib\netstandard1.3\Microsoft.AspNetCore.Cryptography.Internal.dll C:\Users\raines\.dotnet\NuGetFallbackFolder\microsoft.aspnetcore.cryptography.keyderivation\2.0.0-preview1-final\lib\netstandard1.3\Microsoft.AspNetCore.Cryptography.KeyDerivation.dll C:\Users\raines\.dotnet\NuGetFallbackFolder\microsoft.aspnetcore.dataprotection.abstractions\2.0.0-preview1-final\lib\netstandard1.3\Microsoft.AspNetCore.DataProtection.Abstractions.dll C:\Users\raines\.dotnet\NuGetFallbackFolder\microsoft.aspnetcore.dataprotection.azurestorage\2.0.0-preview1-final\lib\netstandard1.5\Microsoft.AspNetCore.DataProtection.AzureStorage.dll C:\Users\raines\.dotnet\NuGetFallbackFolder\microsoft.aspnetcore.dataprotection\2.0.0-preview1-final\lib\netstandard1.3\Microsoft.AspNetCore.DataProtection.dll C:\Users\raines\.dotnet\NuGetFallbackFolder\microsoft.aspnetcore.dataprotection.extensions\2.0.0-preview1-final\lib\netstandard1.3\Microsoft.AspNetCore.DataProtection.Extensions.dll C:\Users\raines\.dotnet\NuGetFallbackFolder\microsoft.aspnetcore.diagnostics.abstractions\2.0.0-preview1-final\lib\netcoreapp2.0\Microsoft.AspNetCore.Diagnostics.Abstractions.dll C:\Users\raines\.dotnet\NuGetFallbackFolder\microsoft.aspnetcore.diagnostics\2.0.0-preview1-final\lib\netcoreapp2.0\Microsoft.AspNetCore.Diagnostics.dll C:\Users\raines\.dotnet\NuGetFallbackFolder\microsoft.aspnetcore.diagnostics.entityframeworkcore\2.0.0-preview1-final\lib\netcoreapp2.0\Microsoft.AspNetCore.Diagnostics.EntityFrameworkCore.dll C:\Users\raines\.dotnet\NuGetFallbackFolder\microsoft.aspnetcore.diagnostics.identity.service\1.0.0-preview1-final\lib\netcoreapp2.0\Microsoft.AspNetCore.Diagnostics.Identity.Service.dll C:\Users\raines\.dotnet\NuGetFallbackFolder\microsoft.aspnetcore\2.0.0-preview1-final\lib\netcoreapp2.0\Microsoft.AspNetCore.dll C:\Users\raines\.dotnet\NuGetFallbackFolder\microsoft.aspnetcore.hosting.abstractions\2.0.0-preview1-final\lib\netcoreapp2.0\Microsoft.AspNetCore.Hosting.Abstractions.dll C:\Users\raines\.dotnet\NuGetFallbackFolder\microsoft.aspnetcore.hosting\2.0.0-preview1-final\lib\netcoreapp2.0\Microsoft.AspNetCore.Hosting.dll C:\Users\raines\.dotnet\NuGetFallbackFolder\microsoft.aspnetcore.hosting.server.abstractions\2.0.0-preview1-final\lib\netcoreapp2.0\Microsoft.AspNetCore.Hosting.Server.Abstractions.dll C:\Users\raines\.dotnet\NuGetFallbackFolder\microsoft.aspnetcore.html.abstractions\2.0.0-preview1-final\lib\netstandard1.0\Microsoft.AspNetCore.Html.Abstractions.dll C:\Users\raines\.dotnet\NuGetFallbackFolder\microsoft.aspnetcore.http.abstractions\2.0.0-preview1-final\lib\netcoreapp2.0\Microsoft.AspNetCore.Http.Abstractions.dll C:\Users\raines\.dotnet\NuGetFallbackFolder\microsoft.aspnetcore.http\2.0.0-preview1-final\lib\netcoreapp2.0\Microsoft.AspNetCore.Http.dll C:\Users\raines\.dotnet\NuGetFallbackFolder\microsoft.aspnetcore.http.extensions\2.0.0-preview1-final\lib\netcoreapp2.0\Microsoft.AspNetCore.Http.Extensions.dll C:\Users\raines\.dotnet\NuGetFallbackFolder\microsoft.aspnetcore.http.features\2.0.0-preview1-final\lib\netcoreapp2.0\Microsoft.AspNetCore.Http.Features.dll C:\Users\raines\.dotnet\NuGetFallbackFolder\microsoft.aspnetcore.httpoverrides\2.0.0-preview1-final\lib\netcoreapp2.0\Microsoft.AspNetCore.HttpOverrides.dll C:\Users\raines\.dotnet\NuGetFallbackFolder\microsoft.aspnetcore.identity\2.0.0-preview1-final\lib\netcoreapp2.0\Microsoft.AspNetCore.Identity.dll C:\Users\raines\.dotnet\NuGetFallbackFolder\microsoft.aspnetcore.identity.entityframeworkcore\2.0.0-preview1-final\lib\netcoreapp2.0\Microsoft.AspNetCore.Identity.EntityFrameworkCore.dll C:\Users\raines\.dotnet\NuGetFallbackFolder\microsoft.aspnetcore.identity.service.abstractions\1.0.0-preview1-final\lib\netcoreapp2.0\Microsoft.AspNetCore.Identity.Service.Abstractions.dll C:\Users\raines\.dotnet\NuGetFallbackFolder\microsoft.aspnetcore.identity.service.core\1.0.0-preview1-final\lib\netcoreapp2.0\Microsoft.AspNetCore.Identity.Service.Core.dll C:\Users\raines\.dotnet\NuGetFallbackFolder\microsoft.aspnetcore.identity.service\1.0.0-preview1-final\lib\netcoreapp2.0\Microsoft.AspNetCore.Identity.Service.dll C:\Users\raines\.dotnet\NuGetFallbackFolder\microsoft.aspnetcore.identity.service.entityframeworkcore\1.0.0-preview1-final\lib\netcoreapp2.0\Microsoft.AspNetCore.Identity.Service.EntityFrameworkCore.dll C:\Users\raines\.dotnet\NuGetFallbackFolder\microsoft.aspnetcore.identity.service.integratedwebclient\1.0.0-preview1-final\lib\netcoreapp2.0\Microsoft.AspNetCore.Identity.Service.IntegratedWebClient.dll C:\Users\raines\.dotnet\NuGetFallbackFolder\microsoft.aspnetcore.identity.service.mvc\1.0.0-preview1-final\lib\netcoreapp2.0\Microsoft.AspNetCore.Identity.Service.Mvc.dll C:\Users\raines\.dotnet\NuGetFallbackFolder\microsoft.aspnetcore.jsonpatch\2.0.0-preview1-final\lib\netcoreapp2.0\Microsoft.AspNetCore.JsonPatch.dll C:\Users\raines\.dotnet\NuGetFallbackFolder\microsoft.aspnetcore.localization\2.0.0-preview1-final\lib\netcoreapp2.0\Microsoft.AspNetCore.Localization.dll C:\Users\raines\.dotnet\NuGetFallbackFolder\microsoft.aspnetcore.localization.routing\2.0.0-preview1-final\lib\netcoreapp2.0\Microsoft.AspNetCore.Localization.Routing.dll C:\Users\raines\.dotnet\NuGetFallbackFolder\microsoft.aspnetcore.middlewareanalysis\2.0.0-preview1-final\lib\netcoreapp2.0\Microsoft.AspNetCore.MiddlewareAnalysis.dll C:\Users\raines\.dotnet\NuGetFallbackFolder\microsoft.aspnetcore.mvc.abstractions\2.0.0-preview1-final\lib\netcoreapp2.0\Microsoft.AspNetCore.Mvc.Abstractions.dll C:\Users\raines\.dotnet\NuGetFallbackFolder\microsoft.aspnetcore.mvc.apiexplorer\2.0.0-preview1-final\lib\netcoreapp2.0\Microsoft.AspNetCore.Mvc.ApiExplorer.dll C:\Users\raines\.dotnet\NuGetFallbackFolder\microsoft.aspnetcore.mvc.core\2.0.0-preview1-final\lib\netcoreapp2.0\Microsoft.AspNetCore.Mvc.Core.dll C:\Users\raines\.dotnet\NuGetFallbackFolder\microsoft.aspnetcore.mvc.cors\2.0.0-preview1-final\lib\netcoreapp2.0\Microsoft.AspNetCore.Mvc.Cors.dll C:\Users\raines\.dotnet\NuGetFallbackFolder\microsoft.aspnetcore.mvc.dataannotations\2.0.0-preview1-final\lib\netcoreapp2.0\Microsoft.AspNetCore.Mvc.DataAnnotations.dll C:\Users\raines\.dotnet\NuGetFallbackFolder\microsoft.aspnetcore.mvc\2.0.0-preview1-final\lib\netcoreapp2.0\Microsoft.AspNetCore.Mvc.dll C:\Users\raines\.dotnet\NuGetFallbackFolder\microsoft.aspnetcore.mvc.formatters.json\2.0.0-preview1-final\lib\netcoreapp2.0\Microsoft.AspNetCore.Mvc.Formatters.Json.dll C:\Users\raines\.dotnet\NuGetFallbackFolder\microsoft.aspnetcore.mvc.formatters.xml\2.0.0-preview1-final\lib\netcoreapp2.0\Microsoft.AspNetCore.Mvc.Formatters.Xml.dll C:\Users\raines\.dotnet\NuGetFallbackFolder\microsoft.aspnetcore.mvc.localization\2.0.0-preview1-final\lib\netcoreapp2.0\Microsoft.AspNetCore.Mvc.Localization.dll C:\Users\raines\.dotnet\NuGetFallbackFolder\microsoft.aspnetcore.mvc.razor\2.0.0-preview1-final\lib\netcoreapp2.0\Microsoft.AspNetCore.Mvc.Razor.dll C:\Users\raines\.dotnet\NuGetFallbackFolder\microsoft.aspnetcore.mvc.razor.extensions\2.0.0-preview1-final\lib\netstandard1.3\Microsoft.AspNetCore.Mvc.Razor.Extensions.dll C:\Users\raines\.dotnet\NuGetFallbackFolder\microsoft.aspnetcore.mvc.razorpages\2.0.0-preview1-final\lib\netcoreapp2.0\Microsoft.AspNetCore.Mvc.RazorPages.dll C:\Users\raines\.dotnet\NuGetFallbackFolder\microsoft.aspnetcore.mvc.taghelpers\2.0.0-preview1-final\lib\netcoreapp2.0\Microsoft.AspNetCore.Mvc.TagHelpers.dll C:\Users\raines\.dotnet\NuGetFallbackFolder\microsoft.aspnetcore.mvc.viewfeatures\2.0.0-preview1-final\lib\netcoreapp2.0\Microsoft.AspNetCore.Mvc.ViewFeatures.dll C:\Users\raines\.dotnet\NuGetFallbackFolder\microsoft.aspnetcore.owin\2.0.0-preview1-final\lib\netcoreapp2.0\Microsoft.AspNetCore.Owin.dll C:\Users\raines\.dotnet\NuGetFallbackFolder\microsoft.aspnetcore.razor\2.0.0-preview1-final\lib\netstandard1.3\Microsoft.AspNetCore.Razor.dll C:\Users\raines\.dotnet\NuGetFallbackFolder\microsoft.aspnetcore.razor.language\2.0.0-preview1-final\lib\netstandard1.3\Microsoft.AspNetCore.Razor.Language.dll C:\Users\raines\.dotnet\NuGetFallbackFolder\microsoft.aspnetcore.razor.runtime\2.0.0-preview1-final\lib\netstandard1.5\Microsoft.AspNetCore.Razor.Runtime.dll C:\Users\raines\.dotnet\NuGetFallbackFolder\microsoft.aspnetcore.responsecaching.abstractions\2.0.0-preview1-final\lib\netcoreapp2.0\Microsoft.AspNetCore.ResponseCaching.Abstractions.dll C:\Users\raines\.dotnet\NuGetFallbackFolder\microsoft.aspnetcore.responsecaching\2.0.0-preview1-final\lib\netcoreapp2.0\Microsoft.AspNetCore.ResponseCaching.dll C:\Users\raines\.dotnet\NuGetFallbackFolder\microsoft.aspnetcore.responsecompression\2.0.0-preview1-final\lib\netcoreapp2.0\Microsoft.AspNetCore.ResponseCompression.dll C:\Users\raines\.dotnet\NuGetFallbackFolder\microsoft.aspnetcore.rewrite\2.0.0-preview1-final\lib\netcoreapp2.0\Microsoft.AspNetCore.Rewrite.dll C:\Users\raines\.dotnet\NuGetFallbackFolder\microsoft.aspnetcore.routing.abstractions\2.0.0-preview1-final\lib\netcoreapp2.0\Microsoft.AspNetCore.Routing.Abstractions.dll C:\Users\raines\.dotnet\NuGetFallbackFolder\microsoft.aspnetcore.routing\2.0.0-preview1-final\lib\netcoreapp2.0\Microsoft.AspNetCore.Routing.dll C:\Users\raines\.dotnet\NuGetFallbackFolder\microsoft.aspnetcore.server.httpsys\2.0.0-preview1-final\lib\netcoreapp2.0\Microsoft.AspNetCore.Server.HttpSys.dll C:\Users\raines\.dotnet\NuGetFallbackFolder\microsoft.aspnetcore.server.iisintegration\2.0.0-preview1-final\lib\netcoreapp2.0\Microsoft.AspNetCore.Server.IISIntegration.dll C:\Users\raines\.dotnet\NuGetFallbackFolder\microsoft.aspnetcore.server.kestrel.core\2.0.0-preview1-final\lib\netcoreapp2.0\Microsoft.AspNetCore.Server.Kestrel.Core.dll C:\Users\raines\.dotnet\NuGetFallbackFolder\microsoft.aspnetcore.server.kestrel\2.0.0-preview1-final\lib\netcoreapp2.0\Microsoft.AspNetCore.Server.Kestrel.dll C:\Users\raines\.dotnet\NuGetFallbackFolder\microsoft.aspnetcore.server.kestrel.https\2.0.0-preview1-final\lib\netcoreapp2.0\Microsoft.AspNetCore.Server.Kestrel.Https.dll C:\Users\raines\.dotnet\NuGetFallbackFolder\microsoft.aspnetcore.server.kestrel.transport.abstractions\2.0.0-preview1-final\lib\netcoreapp2.0\Microsoft.AspNetCore.Server.Kestrel.Transport.Abstractions.dll C:\Users\raines\.dotnet\NuGetFallbackFolder\microsoft.aspnetcore.server.kestrel.transport.libuv\2.0.0-preview1-final\lib\netcoreapp2.0\Microsoft.AspNetCore.Server.Kestrel.Transport.Libuv.dll C:\Users\raines\.dotnet\NuGetFallbackFolder\microsoft.aspnetcore.server.kestrel.transport.sockets\2.0.0-preview1-final\lib\netcoreapp2.0\Microsoft.AspNetCore.Server.Kestrel.Transport.Sockets.dll C:\Users\raines\.dotnet\NuGetFallbackFolder\microsoft.aspnetcore.session\2.0.0-preview1-final\lib\netcoreapp2.0\Microsoft.AspNetCore.Session.dll C:\Users\raines\.dotnet\NuGetFallbackFolder\microsoft.aspnetcore.staticfiles\2.0.0-preview1-final\lib\netcoreapp2.0\Microsoft.AspNetCore.StaticFiles.dll C:\Users\raines\.dotnet\NuGetFallbackFolder\microsoft.aspnetcore.websockets\2.0.0-preview1-final\lib\netcoreapp2.0\Microsoft.AspNetCore.WebSockets.dll C:\Users\raines\.dotnet\NuGetFallbackFolder\microsoft.aspnetcore.webutilities\2.0.0-preview1-final\lib\netcoreapp2.0\Microsoft.AspNetCore.WebUtilities.dll C:\Users\raines\.dotnet\NuGetFallbackFolder\microsoft.azure.keyvault\2.2.1-preview\lib\netstandard1.4\Microsoft.Azure.KeyVault.dll C:\Users\raines\.dotnet\NuGetFallbackFolder\microsoft.azure.keyvault.webkey\2.0.5\lib\netstandard1.4\Microsoft.Azure.KeyVault.WebKey.dll C:\Users\raines\.dotnet\NuGetFallbackFolder\microsoft.codeanalysis.csharp\2.0.0\lib\netstandard1.3\Microsoft.CodeAnalysis.CSharp.dll C:\Users\raines\.dotnet\NuGetFallbackFolder\microsoft.codeanalysis.common\2.0.0\lib\netstandard1.3\Microsoft.CodeAnalysis.dll C:\Users\raines\.dotnet\NuGetFallbackFolder\microsoft.codeanalysis.razor\2.0.0-preview1-final\lib\netstandard1.3\Microsoft.CodeAnalysis.Razor.dll C:\Users\raines\.dotnet\NuGetFallbackFolder\microsoft.netcore.app\2.0.0-preview1-002111-00\ref\netcoreapp2.0\Microsoft.CSharp.dll C:\Users\raines\.dotnet\NuGetFallbackFolder\microsoft.data.edm\5.8.2\lib\netstandard1.1\Microsoft.Data.Edm.dll C:\Users\raines\.dotnet\NuGetFallbackFolder\microsoft.data.odata\5.8.2\lib\netstandard1.1\Microsoft.Data.OData.dll C:\Users\raines\.dotnet\NuGetFallbackFolder\microsoft.data.sqlite.core\2.0.0-preview1-final\lib\netstandard1.2\Microsoft.Data.Sqlite.dll C:\Users\raines\.dotnet\NuGetFallbackFolder\microsoft.dotnet.platformabstractions\2.0.0-preview1-002111\lib\netstandard1.3\Microsoft.DotNet.PlatformAbstractions.dll C:\Users\raines\.dotnet\NuGetFallbackFolder\microsoft.entityframeworkcore.design\2.0.0-preview1-final\lib\netstandard1.3\Microsoft.EntityFrameworkCore.Design.dll C:\Users\raines\.dotnet\NuGetFallbackFolder\microsoft.entityframeworkcore\2.0.0-preview1-final\lib\netstandard1.3\Microsoft.EntityFrameworkCore.dll C:\Users\raines\.dotnet\NuGetFallbackFolder\microsoft.entityframeworkcore.inmemory\2.0.0-preview1-final\lib\netstandard1.3\Microsoft.EntityFrameworkCore.InMemory.dll C:\Users\raines\.dotnet\NuGetFallbackFolder\microsoft.entityframeworkcore.relational.design\2.0.0-preview1-final\lib\netstandard1.3\Microsoft.EntityFrameworkCore.Relational.Design.dll C:\Users\raines\.dotnet\NuGetFallbackFolder\microsoft.entityframeworkcore.relational\2.0.0-preview1-final\lib\netstandard1.3\Microsoft.EntityFrameworkCore.Relational.dll C:\Users\raines\.dotnet\NuGetFallbackFolder\microsoft.entityframeworkcore.sqlite.design\2.0.0-preview1-final\lib\netstandard1.3\Microsoft.EntityFrameworkCore.Sqlite.Design.dll C:\Users\raines\.dotnet\NuGetFallbackFolder\microsoft.entityframeworkcore.sqlite.core\2.0.0-preview1-final\lib\netstandard1.3\Microsoft.EntityFrameworkCore.Sqlite.dll C:\Users\raines\.dotnet\NuGetFallbackFolder\microsoft.entityframeworkcore.sqlserver.design\2.0.0-preview1-final\lib\netstandard1.3\Microsoft.EntityFrameworkCore.SqlServer.Design.dll C:\Users\raines\.dotnet\NuGetFallbackFolder\microsoft.entityframeworkcore.sqlserver\2.0.0-preview1-final\lib\netstandard1.3\Microsoft.EntityFrameworkCore.SqlServer.dll C:\Users\raines\.dotnet\NuGetFallbackFolder\microsoft.extensions.caching.abstractions\2.0.0-preview1-final\lib\netstandard1.0\Microsoft.Extensions.Caching.Abstractions.dll C:\Users\raines\.dotnet\NuGetFallbackFolder\microsoft.extensions.caching.memory\2.0.0-preview1-final\lib\netstandard1.3\Microsoft.Extensions.Caching.Memory.dll C:\Users\raines\.dotnet\NuGetFallbackFolder\microsoft.extensions.caching.redis\2.0.0-preview1-final\lib\netstandard1.5\Microsoft.Extensions.Caching.Redis.dll C:\Users\raines\.dotnet\NuGetFallbackFolder\microsoft.extensions.caching.sqlserver\2.0.0-preview1-final\lib\netstandard1.2\Microsoft.Extensions.Caching.SqlServer.dll C:\Users\raines\.dotnet\NuGetFallbackFolder\microsoft.extensions.configuration.abstractions\2.0.0-preview1-final\lib\netstandard1.0\Microsoft.Extensions.Configuration.Abstractions.dll C:\Users\raines\.dotnet\NuGetFallbackFolder\microsoft.extensions.configuration.azurekeyvault\2.0.0-preview1-final\lib\netstandard1.5\Microsoft.Extensions.Configuration.AzureKeyVault.dll C:\Users\raines\.dotnet\NuGetFallbackFolder\microsoft.extensions.configuration.binder\2.0.0-preview1-final\lib\netstandard1.1\Microsoft.Extensions.Configuration.Binder.dll C:\Users\raines\.dotnet\NuGetFallbackFolder\microsoft.extensions.configuration.commandline\2.0.0-preview1-final\lib\netstandard1.1\Microsoft.Extensions.Configuration.CommandLine.dll C:\Users\raines\.dotnet\NuGetFallbackFolder\microsoft.extensions.configuration\2.0.0-preview1-final\lib\netstandard1.1\Microsoft.Extensions.Configuration.dll C:\Users\raines\.dotnet\NuGetFallbackFolder\microsoft.extensions.configuration.dockersecrets\2.0.0-preview1-final\lib\netstandard1.3\Microsoft.Extensions.Configuration.DockerSecrets.dll C:\Users\raines\.dotnet\NuGetFallbackFolder\microsoft.extensions.configuration.environmentvariables\2.0.0-preview1-final\lib\netstandard1.3\Microsoft.Extensions.Configuration.EnvironmentVariables.dll C:\Users\raines\.dotnet\NuGetFallbackFolder\microsoft.extensions.configuration.fileextensions\2.0.0-preview1-final\lib\netstandard1.3\Microsoft.Extensions.Configuration.FileExtensions.dll C:\Users\raines\.dotnet\NuGetFallbackFolder\microsoft.extensions.configuration.ini\2.0.0-preview1-final\lib\netstandard1.3\Microsoft.Extensions.Configuration.Ini.dll C:\Users\raines\.dotnet\NuGetFallbackFolder\microsoft.extensions.configuration.json\2.0.0-preview1-final\lib\netstandard1.3\Microsoft.Extensions.Configuration.Json.dll C:\Users\raines\.dotnet\NuGetFallbackFolder\microsoft.extensions.configuration.usersecrets\2.0.0-preview1-final\lib\netstandard1.3\Microsoft.Extensions.Configuration.UserSecrets.dll C:\Users\raines\.dotnet\NuGetFallbackFolder\microsoft.extensions.configuration.xml\2.0.0-preview1-final\lib\netstandard1.3\Microsoft.Extensions.Configuration.Xml.dll C:\Users\raines\.dotnet\NuGetFallbackFolder\microsoft.extensions.dependencyinjection.abstractions\2.0.0-preview1-final\lib\netstandard1.0\Microsoft.Extensions.DependencyInjection.Abstractions.dll C:\Users\raines\.dotnet\NuGetFallbackFolder\microsoft.extensions.dependencyinjection\2.0.0-preview1-final\lib\netstandard1.1\Microsoft.Extensions.DependencyInjection.dll C:\Users\raines\.dotnet\NuGetFallbackFolder\microsoft.extensions.dependencymodel\2.0.0-preview1-002111\lib\netstandard1.6\Microsoft.Extensions.DependencyModel.dll C:\Users\raines\.dotnet\NuGetFallbackFolder\microsoft.extensions.diagnosticadapter\2.0.0-preview1-final\lib\netstandard1.1\Microsoft.Extensions.DiagnosticAdapter.dll C:\Users\raines\.dotnet\NuGetFallbackFolder\microsoft.extensions.fileproviders.abstractions\2.0.0-preview1-final\lib\netstandard1.0\Microsoft.Extensions.FileProviders.Abstractions.dll C:\Users\raines\.dotnet\NuGetFallbackFolder\microsoft.extensions.fileproviders.composite\2.0.0-preview1-final\lib\netstandard1.0\Microsoft.Extensions.FileProviders.Composite.dll C:\Users\raines\.dotnet\NuGetFallbackFolder\microsoft.extensions.fileproviders.embedded\2.0.0-preview1-final\lib\netstandard1.5\Microsoft.Extensions.FileProviders.Embedded.dll C:\Users\raines\.dotnet\NuGetFallbackFolder\microsoft.extensions.fileproviders.physical\2.0.0-preview1-final\lib\netstandard1.3\Microsoft.Extensions.FileProviders.Physical.dll C:\Users\raines\.dotnet\NuGetFallbackFolder\microsoft.extensions.filesystemglobbing\2.0.0-preview1-final\lib\netstandard1.3\Microsoft.Extensions.FileSystemGlobbing.dll C:\Users\raines\.dotnet\NuGetFallbackFolder\microsoft.extensions.hosting.abstractions\2.0.0-preview1-final\lib\netcoreapp2.0\Microsoft.Extensions.Hosting.Abstractions.dll C:\Users\raines\.dotnet\NuGetFallbackFolder\microsoft.extensions.localization.abstractions\2.0.0-preview1-final\lib\netstandard1.0\Microsoft.Extensions.Localization.Abstractions.dll C:\Users\raines\.dotnet\NuGetFallbackFolder\microsoft.extensions.localization\2.0.0-preview1-final\lib\netstandard1.3\Microsoft.Extensions.Localization.dll C:\Users\raines\.dotnet\NuGetFallbackFolder\microsoft.extensions.logging.abstractions\2.0.0-preview1-final\lib\netstandard1.1\Microsoft.Extensions.Logging.Abstractions.dll C:\Users\raines\.dotnet\NuGetFallbackFolder\microsoft.extensions.logging.console\2.0.0-preview1-final\lib\netstandard1.3\Microsoft.Extensions.Logging.Console.dll C:\Users\raines\.dotnet\NuGetFallbackFolder\microsoft.extensions.logging.debug\2.0.0-preview1-final\lib\netstandard1.3\Microsoft.Extensions.Logging.Debug.dll C:\Users\raines\.dotnet\NuGetFallbackFolder\microsoft.extensions.logging\2.0.0-preview1-final\lib\netstandard1.1\Microsoft.Extensions.Logging.dll C:\Users\raines\.dotnet\NuGetFallbackFolder\microsoft.extensions.logging.eventsource\2.0.0-preview1-final\lib\netstandard1.3\Microsoft.Extensions.Logging.EventSource.dll C:\Users\raines\.dotnet\NuGetFallbackFolder\microsoft.extensions.logging.tracesource\2.0.0-preview1-final\lib\netstandard1.3\Microsoft.Extensions.Logging.TraceSource.dll C:\Users\raines\.dotnet\NuGetFallbackFolder\microsoft.extensions.objectpool\2.0.0-preview1-final\lib\netstandard1.3\Microsoft.Extensions.ObjectPool.dll C:\Users\raines\.dotnet\NuGetFallbackFolder\microsoft.extensions.options.configurationextensions\2.0.0-preview1-final\lib\netstandard1.1\Microsoft.Extensions.Options.ConfigurationExtensions.dll C:\Users\raines\.dotnet\NuGetFallbackFolder\microsoft.extensions.options\2.0.0-preview1-final\lib\netstandard1.1\Microsoft.Extensions.Options.dll C:\Users\raines\.dotnet\NuGetFallbackFolder\microsoft.extensions.primitives\2.0.0-preview1-final\lib\netstandard1.0\Microsoft.Extensions.Primitives.dll C:\Users\raines\.dotnet\NuGetFallbackFolder\microsoft.extensions.webencoders\2.0.0-preview1-final\lib\netstandard1.1\Microsoft.Extensions.WebEncoders.dll C:\Users\raines\.dotnet\NuGetFallbackFolder\microsoft.identitymodel.clients.activedirectory\3.13.5\lib\netstandard1.4\Microsoft.IdentityModel.Clients.ActiveDirectory.dll C:\Users\raines\.dotnet\NuGetFallbackFolder\microsoft.identitymodel.clients.activedirectory\3.13.5\lib\netstandard1.4\Microsoft.IdentityModel.Clients.ActiveDirectory.Platform.dll C:\Users\raines\.dotnet\NuGetFallbackFolder\microsoft.identitymodel.logging\1.1.3\lib\netstandard1.4\Microsoft.IdentityModel.Logging.dll C:\Users\raines\.dotnet\NuGetFallbackFolder\microsoft.identitymodel.protocols\2.1.3\lib\netstandard1.4\Microsoft.IdentityModel.Protocols.dll C:\Users\raines\.dotnet\NuGetFallbackFolder\microsoft.identitymodel.protocols.openidconnect\2.1.3\lib\netstandard1.4\Microsoft.IdentityModel.Protocols.OpenIdConnect.dll C:\Users\raines\.dotnet\NuGetFallbackFolder\microsoft.identitymodel.tokens\5.1.3\lib\netstandard1.4\Microsoft.IdentityModel.Tokens.dll C:\Users\raines\.dotnet\NuGetFallbackFolder\microsoft.net.http.headers\2.0.0-preview1-final\lib\netcoreapp2.0\Microsoft.Net.Http.Headers.dll C:\Users\raines\.dotnet\NuGetFallbackFolder\microsoft.rest.clientruntime.azure\3.3.6\lib\netstandard1.4\Microsoft.Rest.ClientRuntime.Azure.dll C:\Users\raines\.dotnet\NuGetFallbackFolder\microsoft.rest.clientruntime\2.3.7\lib\netstandard1.4\Microsoft.Rest.ClientRuntime.dll C:\Users\raines\.dotnet\NuGetFallbackFolder\microsoft.netcore.app\2.0.0-preview1-002111-00\ref\netcoreapp2.0\Microsoft.VisualBasic.dll C:\Users\raines\.dotnet\NuGetFallbackFolder\microsoft.visualstudio.web.browserlink\2.0.0-preview1-final\lib\netcoreapp2.0\Microsoft.VisualStudio.Web.BrowserLink.dll C:\Users\raines\.dotnet\NuGetFallbackFolder\microsoft.netcore.app\2.0.0-preview1-002111-00\ref\netcoreapp2.0\Microsoft.Win32.Primitives.dll C:\Users\raines\.dotnet\NuGetFallbackFolder\microsoft.win32.registry\4.4.0-preview1-25305-02\ref\netstandard2.0\Microsoft.Win32.Registry.dll C:\Users\raines\.dotnet\NuGetFallbackFolder\windowsazure.storage\8.1.1\lib\netstandard1.3\Microsoft.WindowsAzure.Storage.dll C:\Users\raines\.dotnet\NuGetFallbackFolder\microsoft.netcore.app\2.0.0-preview1-002111-00\ref\netcoreapp2.0\mscorlib.dll C:\Users\raines\.dotnet\NuGetFallbackFolder\microsoft.netcore.app\2.0.0-preview1-002111-00\ref\netcoreapp2.0\netstandard.dll C:\Users\raines\.dotnet\NuGetFallbackFolder\newtonsoft.json.bson\1.0.1\lib\netstandard1.3\Newtonsoft.Json.Bson.dll C:\Users\raines\.dotnet\NuGetFallbackFolder\newtonsoft.json\10.0.1\lib\netstandard1.3\Newtonsoft.Json.dll C:\Users\raines\.nuget\packages\remotion.linq\2.1.1\lib\netstandard1.0\Remotion.Linq.dll C:\Users\raines\.dotnet\NuGetFallbackFolder\sqlitepclraw.bundle_green\1.1.5\lib\netcoreapp\SQLitePCLRaw.batteries_green.dll C:\Users\raines\.dotnet\NuGetFallbackFolder\sqlitepclraw.bundle_green\1.1.5\lib\netcoreapp\SQLitePCLRaw.batteries_v2.dll C:\Users\raines\.dotnet\NuGetFallbackFolder\sqlitepclraw.core\1.1.5\lib\netstandard1.1\SQLitePCLRaw.core.dll C:\Users\raines\.dotnet\NuGetFallbackFolder\sqlitepclraw.provider.e_sqlite3.netstandard11\1.1.5\lib\netstandard1.1\SQLitePCLRaw.provider.e_sqlite3.dll C:\Users\raines\.dotnet\NuGetFallbackFolder\stackexchange.redis.strongname\1.2.3\lib\netstandard1.5\StackExchange.Redis.StrongName.dll C:\Users\raines\.dotnet\NuGetFallbackFolder\microsoft.netcore.app\2.0.0-preview1-002111-00\ref\netcoreapp2.0\System.AppContext.dll C:\Users\raines\.dotnet\NuGetFallbackFolder\microsoft.netcore.app\2.0.0-preview1-002111-00\ref\netcoreapp2.0\System.Buffers.dll C:\Users\raines\.dotnet\NuGetFallbackFolder\microsoft.netcore.app\2.0.0-preview1-002111-00\ref\netcoreapp2.0\System.Collections.Concurrent.dll C:\Users\raines\.dotnet\NuGetFallbackFolder\microsoft.netcore.app\2.0.0-preview1-002111-00\ref\netcoreapp2.0\System.Collections.dll C:\Users\raines\.dotnet\NuGetFallbackFolder\microsoft.netcore.app\2.0.0-preview1-002111-00\ref\netcoreapp2.0\System.Collections.Immutable.dll C:\Users\raines\.dotnet\NuGetFallbackFolder\microsoft.netcore.app\2.0.0-preview1-002111-00\ref\netcoreapp2.0\System.Collections.NonGeneric.dll C:\Users\raines\.dotnet\NuGetFallbackFolder\microsoft.netcore.app\2.0.0-preview1-002111-00\ref\netcoreapp2.0\System.Collections.Specialized.dll C:\Users\raines\.dotnet\NuGetFallbackFolder\microsoft.netcore.app\2.0.0-preview1-002111-00\ref\netcoreapp2.0\System.ComponentModel.Annotations.dll C:\Users\raines\.dotnet\NuGetFallbackFolder\microsoft.netcore.app\2.0.0-preview1-002111-00\ref\netcoreapp2.0\System.ComponentModel.Composition.dll C:\Users\raines\.dotnet\NuGetFallbackFolder\microsoft.netcore.app\2.0.0-preview1-002111-00\ref\netcoreapp2.0\System.ComponentModel.DataAnnotations.dll C:\Users\raines\.dotnet\NuGetFallbackFolder\microsoft.netcore.app\2.0.0-preview1-002111-00\ref\netcoreapp2.0\System.ComponentModel.dll C:\Users\raines\.dotnet\NuGetFallbackFolder\microsoft.netcore.app\2.0.0-preview1-002111-00\ref\netcoreapp2.0\System.ComponentModel.EventBasedAsync.dll C:\Users\raines\.dotnet\NuGetFallbackFolder\microsoft.netcore.app\2.0.0-preview1-002111-00\ref\netcoreapp2.0\System.ComponentModel.Primitives.dll C:\Users\raines\.dotnet\NuGetFallbackFolder\microsoft.netcore.app\2.0.0-preview1-002111-00\ref\netcoreapp2.0\System.ComponentModel.TypeConverter.dll C:\Users\raines\.dotnet\NuGetFallbackFolder\microsoft.netcore.app\2.0.0-preview1-002111-00\ref\netcoreapp2.0\System.Console.dll C:\Users\raines\.dotnet\NuGetFallbackFolder\microsoft.netcore.app\2.0.0-preview1-002111-00\ref\netcoreapp2.0\System.Core.dll C:\Users\raines\.dotnet\NuGetFallbackFolder\microsoft.netcore.app\2.0.0-preview1-002111-00\ref\netcoreapp2.0\System.Data.Common.dll C:\Users\raines\.dotnet\NuGetFallbackFolder\microsoft.netcore.app\2.0.0-preview1-002111-00\ref\netcoreapp2.0\System.Data.dll C:\Users\raines\.dotnet\NuGetFallbackFolder\system.data.sqlclient\4.4.0-preview1-25305-02\ref\netstandard2.0\System.Data.SqlClient.dll C:\Users\raines\.dotnet\NuGetFallbackFolder\microsoft.netcore.app\2.0.0-preview1-002111-00\ref\netcoreapp2.0\System.Diagnostics.Contracts.dll C:\Users\raines\.dotnet\NuGetFallbackFolder\microsoft.netcore.app\2.0.0-preview1-002111-00\ref\netcoreapp2.0\System.Diagnostics.Debug.dll C:\Users\raines\.dotnet\NuGetFallbackFolder\microsoft.netcore.app\2.0.0-preview1-002111-00\ref\netcoreapp2.0\System.Diagnostics.DiagnosticSource.dll C:\Users\raines\.dotnet\NuGetFallbackFolder\microsoft.netcore.app\2.0.0-preview1-002111-00\ref\netcoreapp2.0\System.Diagnostics.FileVersionInfo.dll C:\Users\raines\.dotnet\NuGetFallbackFolder\microsoft.netcore.app\2.0.0-preview1-002111-00\ref\netcoreapp2.0\System.Diagnostics.Process.dll C:\Users\raines\.dotnet\NuGetFallbackFolder\microsoft.netcore.app\2.0.0-preview1-002111-00\ref\netcoreapp2.0\System.Diagnostics.StackTrace.dll C:\Users\raines\.dotnet\NuGetFallbackFolder\microsoft.netcore.app\2.0.0-preview1-002111-00\ref\netcoreapp2.0\System.Diagnostics.TextWriterTraceListener.dll C:\Users\raines\.dotnet\NuGetFallbackFolder\microsoft.netcore.app\2.0.0-preview1-002111-00\ref\netcoreapp2.0\System.Diagnostics.Tools.dll C:\Users\raines\.dotnet\NuGetFallbackFolder\microsoft.netcore.app\2.0.0-preview1-002111-00\ref\netcoreapp2.0\System.Diagnostics.TraceSource.dll C:\Users\raines\.dotnet\NuGetFallbackFolder\microsoft.netcore.app\2.0.0-preview1-002111-00\ref\netcoreapp2.0\System.Diagnostics.Tracing.dll C:\Users\raines\.dotnet\NuGetFallbackFolder\microsoft.netcore.app\2.0.0-preview1-002111-00\ref\netcoreapp2.0\System.dll C:\Users\raines\.dotnet\NuGetFallbackFolder\microsoft.netcore.app\2.0.0-preview1-002111-00\ref\netcoreapp2.0\System.Drawing.dll C:\Users\raines\.dotnet\NuGetFallbackFolder\microsoft.netcore.app\2.0.0-preview1-002111-00\ref\netcoreapp2.0\System.Drawing.Primitives.dll C:\Users\raines\.dotnet\NuGetFallbackFolder\microsoft.netcore.app\2.0.0-preview1-002111-00\ref\netcoreapp2.0\System.Dynamic.Runtime.dll C:\Users\raines\.dotnet\NuGetFallbackFolder\microsoft.netcore.app\2.0.0-preview1-002111-00\ref\netcoreapp2.0\System.Globalization.Calendars.dll C:\Users\raines\.dotnet\NuGetFallbackFolder\microsoft.netcore.app\2.0.0-preview1-002111-00\ref\netcoreapp2.0\System.Globalization.dll C:\Users\raines\.dotnet\NuGetFallbackFolder\microsoft.netcore.app\2.0.0-preview1-002111-00\ref\netcoreapp2.0\System.Globalization.Extensions.dll C:\Users\raines\.dotnet\NuGetFallbackFolder\system.identitymodel.tokens.jwt\5.1.3\lib\netstandard1.4\System.IdentityModel.Tokens.Jwt.dll C:\Users\raines\.dotnet\NuGetFallbackFolder\system.interactive.async\3.1.1\lib\netstandard1.3\System.Interactive.Async.dll C:\Users\raines\.dotnet\NuGetFallbackFolder\microsoft.netcore.app\2.0.0-preview1-002111-00\ref\netcoreapp2.0\System.IO.Compression.dll C:\Users\raines\.dotnet\NuGetFallbackFolder\microsoft.netcore.app\2.0.0-preview1-002111-00\ref\netcoreapp2.0\System.IO.Compression.FileSystem.dll C:\Users\raines\.dotnet\NuGetFallbackFolder\microsoft.netcore.app\2.0.0-preview1-002111-00\ref\netcoreapp2.0\System.IO.Compression.ZipFile.dll C:\Users\raines\.dotnet\NuGetFallbackFolder\microsoft.netcore.app\2.0.0-preview1-002111-00\ref\netcoreapp2.0\System.IO.dll C:\Users\raines\.dotnet\NuGetFallbackFolder\microsoft.netcore.app\2.0.0-preview1-002111-00\ref\netcoreapp2.0\System.IO.FileSystem.dll C:\Users\raines\.dotnet\NuGetFallbackFolder\microsoft.netcore.app\2.0.0-preview1-002111-00\ref\netcoreapp2.0\System.IO.FileSystem.DriveInfo.dll C:\Users\raines\.dotnet\NuGetFallbackFolder\microsoft.netcore.app\2.0.0-preview1-002111-00\ref\netcoreapp2.0\System.IO.FileSystem.Primitives.dll C:\Users\raines\.dotnet\NuGetFallbackFolder\microsoft.netcore.app\2.0.0-preview1-002111-00\ref\netcoreapp2.0\System.IO.FileSystem.Watcher.dll C:\Users\raines\.dotnet\NuGetFallbackFolder\microsoft.netcore.app\2.0.0-preview1-002111-00\ref\netcoreapp2.0\System.IO.IsolatedStorage.dll C:\Users\raines\.dotnet\NuGetFallbackFolder\microsoft.netcore.app\2.0.0-preview1-002111-00\ref\netcoreapp2.0\System.IO.MemoryMappedFiles.dll C:\Users\raines\.dotnet\NuGetFallbackFolder\microsoft.netcore.app\2.0.0-preview1-002111-00\ref\netcoreapp2.0\System.IO.Pipes.dll C:\Users\raines\.dotnet\NuGetFallbackFolder\microsoft.netcore.app\2.0.0-preview1-002111-00\ref\netcoreapp2.0\System.IO.UnmanagedMemoryStream.dll C:\Users\raines\.dotnet\NuGetFallbackFolder\microsoft.netcore.app\2.0.0-preview1-002111-00\ref\netcoreapp2.0\System.Linq.dll C:\Users\raines\.dotnet\NuGetFallbackFolder\microsoft.netcore.app\2.0.0-preview1-002111-00\ref\netcoreapp2.0\System.Linq.Expressions.dll C:\Users\raines\.dotnet\NuGetFallbackFolder\microsoft.netcore.app\2.0.0-preview1-002111-00\ref\netcoreapp2.0\System.Linq.Parallel.dll C:\Users\raines\.dotnet\NuGetFallbackFolder\microsoft.netcore.app\2.0.0-preview1-002111-00\ref\netcoreapp2.0\System.Linq.Queryable.dll C:\Users\raines\.dotnet\NuGetFallbackFolder\microsoft.netcore.app\2.0.0-preview1-002111-00\ref\netcoreapp2.0\System.Net.dll C:\Users\raines\.dotnet\NuGetFallbackFolder\microsoft.netcore.app\2.0.0-preview1-002111-00\ref\netcoreapp2.0\System.Net.Http.dll C:\Users\raines\.dotnet\NuGetFallbackFolder\microsoft.netcore.app\2.0.0-preview1-002111-00\ref\netcoreapp2.0\System.Net.HttpListener.dll C:\Users\raines\.dotnet\NuGetFallbackFolder\microsoft.netcore.app\2.0.0-preview1-002111-00\ref\netcoreapp2.0\System.Net.Mail.dll C:\Users\raines\.dotnet\NuGetFallbackFolder\microsoft.netcore.app\2.0.0-preview1-002111-00\ref\netcoreapp2.0\System.Net.NameResolution.dll C:\Users\raines\.dotnet\NuGetFallbackFolder\microsoft.netcore.app\2.0.0-preview1-002111-00\ref\netcoreapp2.0\System.Net.NetworkInformation.dll C:\Users\raines\.dotnet\NuGetFallbackFolder\microsoft.netcore.app\2.0.0-preview1-002111-00\ref\netcoreapp2.0\System.Net.Ping.dll C:\Users\raines\.dotnet\NuGetFallbackFolder\microsoft.netcore.app\2.0.0-preview1-002111-00\ref\netcoreapp2.0\System.Net.Primitives.dll C:\Users\raines\.dotnet\NuGetFallbackFolder\microsoft.netcore.app\2.0.0-preview1-002111-00\ref\netcoreapp2.0\System.Net.Requests.dll C:\Users\raines\.dotnet\NuGetFallbackFolder\microsoft.netcore.app\2.0.0-preview1-002111-00\ref\netcoreapp2.0\System.Net.Security.dll C:\Users\raines\.dotnet\NuGetFallbackFolder\microsoft.netcore.app\2.0.0-preview1-002111-00\ref\netcoreapp2.0\System.Net.ServicePoint.dll C:\Users\raines\.dotnet\NuGetFallbackFolder\microsoft.netcore.app\2.0.0-preview1-002111-00\ref\netcoreapp2.0\System.Net.Sockets.dll C:\Users\raines\.dotnet\NuGetFallbackFolder\microsoft.netcore.app\2.0.0-preview1-002111-00\ref\netcoreapp2.0\System.Net.WebClient.dll C:\Users\raines\.dotnet\NuGetFallbackFolder\microsoft.netcore.app\2.0.0-preview1-002111-00\ref\netcoreapp2.0\System.Net.WebHeaderCollection.dll C:\Users\raines\.dotnet\NuGetFallbackFolder\microsoft.netcore.app\2.0.0-preview1-002111-00\ref\netcoreapp2.0\System.Net.WebProxy.dll C:\Users\raines\.dotnet\NuGetFallbackFolder\microsoft.netcore.app\2.0.0-preview1-002111-00\ref\netcoreapp2.0\System.Net.WebSockets.Client.dll C:\Users\raines\.dotnet\NuGetFallbackFolder\microsoft.netcore.app\2.0.0-preview1-002111-00\ref\netcoreapp2.0\System.Net.WebSockets.dll C:\Users\raines\.dotnet\NuGetFallbackFolder\microsoft.netcore.app\2.0.0-preview1-002111-00\ref\netcoreapp2.0\System.Numerics.dll C:\Users\raines\.dotnet\NuGetFallbackFolder\microsoft.netcore.app\2.0.0-preview1-002111-00\ref\netcoreapp2.0\System.Numerics.Vectors.dll C:\Users\raines\.dotnet\NuGetFallbackFolder\microsoft.netcore.app\2.0.0-preview1-002111-00\ref\netcoreapp2.0\System.ObjectModel.dll C:\Users\raines\.dotnet\NuGetFallbackFolder\microsoft.netcore.app\2.0.0-preview1-002111-00\ref\netcoreapp2.0\System.Reflection.DispatchProxy.dll C:\Users\raines\.dotnet\NuGetFallbackFolder\microsoft.netcore.app\2.0.0-preview1-002111-00\ref\netcoreapp2.0\System.Reflection.dll C:\Users\raines\.dotnet\NuGetFallbackFolder\microsoft.netcore.app\2.0.0-preview1-002111-00\ref\netcoreapp2.0\System.Reflection.Emit.dll C:\Users\raines\.dotnet\NuGetFallbackFolder\microsoft.netcore.app\2.0.0-preview1-002111-00\ref\netcoreapp2.0\System.Reflection.Emit.ILGeneration.dll C:\Users\raines\.dotnet\NuGetFallbackFolder\microsoft.netcore.app\2.0.0-preview1-002111-00\ref\netcoreapp2.0\System.Reflection.Emit.Lightweight.dll C:\Users\raines\.dotnet\NuGetFallbackFolder\microsoft.netcore.app\2.0.0-preview1-002111-00\ref\netcoreapp2.0\System.Reflection.Extensions.dll C:\Users\raines\.dotnet\NuGetFallbackFolder\microsoft.netcore.app\2.0.0-preview1-002111-00\ref\netcoreapp2.0\System.Reflection.Metadata.dll C:\Users\raines\.dotnet\NuGetFallbackFolder\microsoft.netcore.app\2.0.0-preview1-002111-00\ref\netcoreapp2.0\System.Reflection.Primitives.dll C:\Users\raines\.dotnet\NuGetFallbackFolder\microsoft.netcore.app\2.0.0-preview1-002111-00\ref\netcoreapp2.0\System.Reflection.TypeExtensions.dll C:\Users\raines\.dotnet\NuGetFallbackFolder\microsoft.netcore.app\2.0.0-preview1-002111-00\ref\netcoreapp2.0\System.Resources.Reader.dll C:\Users\raines\.dotnet\NuGetFallbackFolder\microsoft.netcore.app\2.0.0-preview1-002111-00\ref\netcoreapp2.0\System.Resources.ResourceManager.dll C:\Users\raines\.dotnet\NuGetFallbackFolder\microsoft.netcore.app\2.0.0-preview1-002111-00\ref\netcoreapp2.0\System.Resources.Writer.dll C:\Users\raines\.dotnet\NuGetFallbackFolder\system.runtime.compilerservices.unsafe\4.4.0-preview1-25219-04\ref\netstandard2.0\System.Runtime.CompilerServices.Unsafe.dll C:\Users\raines\.dotnet\NuGetFallbackFolder\microsoft.netcore.app\2.0.0-preview1-002111-00\ref\netcoreapp2.0\System.Runtime.CompilerServices.VisualC.dll C:\Users\raines\.dotnet\NuGetFallbackFolder\microsoft.netcore.app\2.0.0-preview1-002111-00\ref\netcoreapp2.0\System.Runtime.dll C:\Users\raines\.dotnet\NuGetFallbackFolder\microsoft.netcore.app\2.0.0-preview1-002111-00\ref\netcoreapp2.0\System.Runtime.Extensions.dll C:\Users\raines\.dotnet\NuGetFallbackFolder\microsoft.netcore.app\2.0.0-preview1-002111-00\ref\netcoreapp2.0\System.Runtime.Handles.dll C:\Users\raines\.dotnet\NuGetFallbackFolder\microsoft.netcore.app\2.0.0-preview1-002111-00\ref\netcoreapp2.0\System.Runtime.InteropServices.dll C:\Users\raines\.dotnet\NuGetFallbackFolder\microsoft.netcore.app\2.0.0-preview1-002111-00\ref\netcoreapp2.0\System.Runtime.InteropServices.RuntimeInformation.dll C:\Users\raines\.dotnet\NuGetFallbackFolder\microsoft.netcore.app\2.0.0-preview1-002111-00\ref\netcoreapp2.0\System.Runtime.InteropServices.WindowsRuntime.dll C:\Users\raines\.dotnet\NuGetFallbackFolder\microsoft.netcore.app\2.0.0-preview1-002111-00\ref\netcoreapp2.0\System.Runtime.Loader.dll C:\Users\raines\.dotnet\NuGetFallbackFolder\microsoft.netcore.app\2.0.0-preview1-002111-00\ref\netcoreapp2.0\System.Runtime.Numerics.dll C:\Users\raines\.dotnet\NuGetFallbackFolder\microsoft.netcore.app\2.0.0-preview1-002111-00\ref\netcoreapp2.0\System.Runtime.Serialization.dll C:\Users\raines\.dotnet\NuGetFallbackFolder\microsoft.netcore.app\2.0.0-preview1-002111-00\ref\netcoreapp2.0\System.Runtime.Serialization.Formatters.dll C:\Users\raines\.dotnet\NuGetFallbackFolder\microsoft.netcore.app\2.0.0-preview1-002111-00\ref\netcoreapp2.0\System.Runtime.Serialization.Json.dll C:\Users\raines\.dotnet\NuGetFallbackFolder\microsoft.netcore.app\2.0.0-preview1-002111-00\ref\netcoreapp2.0\System.Runtime.Serialization.Primitives.dll C:\Users\raines\.dotnet\NuGetFallbackFolder\microsoft.netcore.app\2.0.0-preview1-002111-00\ref\netcoreapp2.0\System.Runtime.Serialization.Xml.dll C:\Users\raines\.dotnet\NuGetFallbackFolder\system.security.accesscontrol\4.4.0-preview1-25305-02\ref\netstandard2.0\System.Security.AccessControl.dll C:\Users\raines\.dotnet\NuGetFallbackFolder\microsoft.netcore.app\2.0.0-preview1-002111-00\ref\netcoreapp2.0\System.Security.Claims.dll C:\Users\raines\.dotnet\NuGetFallbackFolder\microsoft.netcore.app\2.0.0-preview1-002111-00\ref\netcoreapp2.0\System.Security.Cryptography.Algorithms.dll C:\Users\raines\.dotnet\NuGetFallbackFolder\microsoft.netcore.app\2.0.0-preview1-002111-00\ref\netcoreapp2.0\System.Security.Cryptography.Cng.dll C:\Users\raines\.dotnet\NuGetFallbackFolder\microsoft.netcore.app\2.0.0-preview1-002111-00\ref\netcoreapp2.0\System.Security.Cryptography.Csp.dll C:\Users\raines\.dotnet\NuGetFallbackFolder\microsoft.netcore.app\2.0.0-preview1-002111-00\ref\netcoreapp2.0\System.Security.Cryptography.Encoding.dll C:\Users\raines\.dotnet\NuGetFallbackFolder\microsoft.netcore.app\2.0.0-preview1-002111-00\ref\netcoreapp2.0\System.Security.Cryptography.Primitives.dll C:\Users\raines\.dotnet\NuGetFallbackFolder\microsoft.netcore.app\2.0.0-preview1-002111-00\ref\netcoreapp2.0\System.Security.Cryptography.X509Certificates.dll C:\Users\raines\.dotnet\NuGetFallbackFolder\microsoft.netcore.app\2.0.0-preview1-002111-00\ref\netcoreapp2.0\System.Security.Principal.dll C:\Users\raines\.dotnet\NuGetFallbackFolder\system.security.principal.windows\4.4.0-preview1-25305-02\ref\netstandard2.0\System.Security.Principal.Windows.dll C:\Users\raines\.dotnet\NuGetFallbackFolder\microsoft.netcore.app\2.0.0-preview1-002111-00\ref\netcoreapp2.0\System.Security.SecureString.dll C:\Users\raines\.dotnet\NuGetFallbackFolder\microsoft.netcore.app\2.0.0-preview1-002111-00\ref\netcoreapp2.0\System.ServiceModel.Web.dll C:\Users\raines\.dotnet\NuGetFallbackFolder\system.spatial\5.8.2\lib\netstandard1.1\System.Spatial.dll C:\Users\raines\.dotnet\NuGetFallbackFolder\microsoft.netcore.app\2.0.0-preview1-002111-00\ref\netcoreapp2.0\System.Text.Encoding.dll C:\Users\raines\.dotnet\NuGetFallbackFolder\microsoft.netcore.app\2.0.0-preview1-002111-00\ref\netcoreapp2.0\System.Text.Encoding.Extensions.dll C:\Users\raines\.nuget\packages\system.text.encodings.web\4.3.0\lib\netstandard1.0\System.Text.Encodings.Web.dll C:\Users\raines\.dotnet\NuGetFallbackFolder\microsoft.netcore.app\2.0.0-preview1-002111-00\ref\netcoreapp2.0\System.Text.RegularExpressions.dll C:\Users\raines\.dotnet\NuGetFallbackFolder\microsoft.netcore.app\2.0.0-preview1-002111-00\ref\netcoreapp2.0\System.Threading.dll C:\Users\raines\.dotnet\NuGetFallbackFolder\microsoft.netcore.app\2.0.0-preview1-002111-00\ref\netcoreapp2.0\System.Threading.Overlapped.dll C:\Users\raines\.dotnet\NuGetFallbackFolder\microsoft.netcore.app\2.0.0-preview1-002111-00\ref\netcoreapp2.0\System.Threading.Tasks.Dataflow.dll C:\Users\raines\.dotnet\NuGetFallbackFolder\microsoft.netcore.app\2.0.0-preview1-002111-00\ref\netcoreapp2.0\System.Threading.Tasks.dll C:\Users\raines\.dotnet\NuGetFallbackFolder\microsoft.netcore.app\2.0.0-preview1-002111-00\ref\netcoreapp2.0\System.Threading.Tasks.Extensions.dll C:\Users\raines\.dotnet\NuGetFallbackFolder\microsoft.netcore.app\2.0.0-preview1-002111-00\ref\netcoreapp2.0\System.Threading.Tasks.Parallel.dll C:\Users\raines\.dotnet\NuGetFallbackFolder\microsoft.netcore.app\2.0.0-preview1-002111-00\ref\netcoreapp2.0\System.Threading.Thread.dll C:\Users\raines\.dotnet\NuGetFallbackFolder\microsoft.netcore.app\2.0.0-preview1-002111-00\ref\netcoreapp2.0\System.Threading.ThreadPool.dll C:\Users\raines\.dotnet\NuGetFallbackFolder\microsoft.netcore.app\2.0.0-preview1-002111-00\ref\netcoreapp2.0\System.Threading.Timer.dll C:\Users\raines\.dotnet\NuGetFallbackFolder\microsoft.netcore.app\2.0.0-preview1-002111-00\ref\netcoreapp2.0\System.Transactions.dll C:\Users\raines\.dotnet\NuGetFallbackFolder\microsoft.netcore.app\2.0.0-preview1-002111-00\ref\netcoreapp2.0\System.Transactions.Local.dll C:\Users\raines\.dotnet\NuGetFallbackFolder\microsoft.netcore.app\2.0.0-preview1-002111-00\ref\netcoreapp2.0\System.ValueTuple.dll C:\Users\raines\.dotnet\NuGetFallbackFolder\microsoft.netcore.app\2.0.0-preview1-002111-00\ref\netcoreapp2.0\System.Web.dll C:\Users\raines\.dotnet\NuGetFallbackFolder\microsoft.netcore.app\2.0.0-preview1-002111-00\ref\netcoreapp2.0\System.Web.HttpUtility.dll C:\Users\raines\.dotnet\NuGetFallbackFolder\microsoft.netcore.app\2.0.0-preview1-002111-00\ref\netcoreapp2.0\System.Windows.dll C:\Users\raines\.dotnet\NuGetFallbackFolder\microsoft.netcore.app\2.0.0-preview1-002111-00\ref\netcoreapp2.0\System.Xml.dll C:\Users\raines\.dotnet\NuGetFallbackFolder\microsoft.netcore.app\2.0.0-preview1-002111-00\ref\netcoreapp2.0\System.Xml.Linq.dll C:\Users\raines\.dotnet\NuGetFallbackFolder\microsoft.netcore.app\2.0.0-preview1-002111-00\ref\netcoreapp2.0\System.Xml.ReaderWriter.dll C:\Users\raines\.dotnet\NuGetFallbackFolder\microsoft.netcore.app\2.0.0-preview1-002111-00\ref\netcoreapp2.0\System.Xml.Serialization.dll C:\Users\raines\.dotnet\NuGetFallbackFolder\microsoft.netcore.app\2.0.0-preview1-002111-00\ref\netcoreapp2.0\System.Xml.XDocument.dll C:\Users\raines\.dotnet\NuGetFallbackFolder\microsoft.netcore.app\2.0.0-preview1-002111-00\ref\netcoreapp2.0\System.Xml.XmlDocument.dll C:\Users\raines\.dotnet\NuGetFallbackFolder\microsoft.netcore.app\2.0.0-preview1-002111-00\ref\netcoreapp2.0\System.Xml.XmlSerializer.dll C:\Users\raines\.dotnet\NuGetFallbackFolder\microsoft.netcore.app\2.0.0-preview1-002111-00\ref\netcoreapp2.0\System.Xml.XPath.dll C:\Users\raines\.dotnet\NuGetFallbackFolder\microsoft.netcore.app\2.0.0-preview1-002111-00\ref\netcoreapp2.0\System.Xml.XPath.XDocument.dll ```
DamianEdwards commented 7 years ago

@rainersigwald ahh that makes sense. The ASP.NET Core assemblies account for ~180 of those, the rest are from Microsoft.NETCore.App and NETStandard.Library

rainersigwald commented 7 years ago

You need to run it for full framework on the nuget assemblies as well. It'll find version conflicts and emit bindingRedirects.

I thought version conflicts for NuGet-delivered assemblies were handled by ResolvePackageFileConflicts. @dsplaisted am I misunderstanding the intention there?

ericstj commented 7 years ago

I'm not talking about conflicts of actual references. I'm talking about transitive references. Consider that library A (1.0.0.0) > B (1.0.0.0), and app references A (1.0.0.0) and B (2.0.0.0). RAR will only see A (1.0.0.0) and B (2.0.0.0) but it needs to discover that a bindingRedirect is needed for B. It does that and emits and suggested redirect which gets written to the app.config.

ResolvePackageFileConflicts does not examine transitive references, it's only about handling conflicts in direct references because RAR doesn't touch those.

On desktop the loader is strict and requires you to tell it to redirect a lower version to a higher version.

On .NET Core the loader will automatically load a higher version.

I guess by bypassing RAR we do lose out on the case where someone has explicitly chosen a lower version. Consider the case where A (1.0.0.0) > B (2.0.0.0), but the app referenced B (1.0.0.0). This would cause a ref-def mismatch at runtime even on .NET core. RAR catches this today and we'd lose that by bypassing RAR. Not sure we care because typically this means a package bug, or someone has explicitly downgraded a package (which NuGet should emit a warning for), but that's something to consider.

rainersigwald commented 7 years ago

@ericstj Isn't that a malformed NuGet scenario? The A-1.0 package should have a reference to B-1.0, which is then resolved by NuGet's logic?

I don't understand what the design intention there is for binding redirects--that would be handled better by RAR. But is that what actually happens in a project today?

ericstj commented 7 years ago

@ericstj Isn't that a malformed NuGet scenario? The A-1.0 package should have a reference to B-1.0, which is then resolved by NuGet's logic?

Sure, but then the app references B 2.0 because it wants to use that. Nuget does the right thing and gives the app B 2.0. It's up to RAR to write the redirect. It does this today. See https://github.com/Microsoft/msbuild/blob/6851538897f5d7b08024a6d8435bc44be5869e53/src/Tasks/AssemblyDependency/ResolveAssemblyReference.cs#L853 https://github.com/Microsoft/msbuild/blob/6851538897f5d7b08024a6d8435bc44be5869e53/src/Tasks/AssemblyDependency/GenerateBindingRedirects.cs

Feel free to take this part of the discussion offline. Net result is that RAR is required on desktop for all references. I think for other frameworks there might be some lee-way but we would lose some of the build time checks and push those off to runtime. Might be acceptable.

rainersigwald commented 7 years ago

Ah, I see now--NuGet coughs up a (package-conflict-resolved) A-1.0 and B-2.0 assemblies, which are then fed into RAR, which explores the transitive assembly dependencies of A, finds B-1.0, adds that to the closure of assemblies, and then applies its own assembly-conflict resolution logic to choose B-2.0 and recommend a binding redirect.

That's a great case, thanks.

I think that means we're back to "attempt to cache outputs for unchanged inputs". This hasn't been done historically, because the "inputs" to RAR include things like the GAC, registry keys, and arbitrary filesystem locations--so it's effectively impossible to build the cache key.

But for SDK projects, the really problematic inputs of GAC and registry are already disabled. I think I can live with requiring an explicit user-requested rebuild after installing a .NET SDK (that could change where a reference to System came from). If anyone thinks that would be unacceptable, or sees another machine-state change that would cause problems, please holler.

I'd expect new caching behavior to be put behind an opt-in parameter to RAR, so non-new-SDK projects see no difference, and the SDK can opt in (and if we discover a late-breaking bug, a user could opt back out again).

DamianEdwards commented 7 years ago

@rainersigwald do you have a plan on how/when this would make its way in?

rainersigwald commented 7 years ago

I'm planning to prototype the caching strategy ASAP. Will try to have a more concrete idea of timeline by EOD Tuesday, which we can use to plan for release windows.

DamianEdwards commented 7 years ago

@rainersigwald many thanks! Do we have a rough idea of what would be cached and thus how much time we're looking at saving?

dsplaisted commented 7 years ago

I think that means we're back to "attempt to cache outputs for unchanged inputs".

Skipping RAR for references that already have a path assigned seemed promising for .NET Core projects. Would it be worth doing that unless the project targets .NET Framework, while on .NET Framework everything would still need to go through RAR in order to generate binding redirects?

DamianEdwards commented 7 years ago

If it achieves a good gain then I think we should.

DamianEdwards commented 7 years ago

Any update on this?

rainersigwald commented 7 years ago

So my understanding is there are three interesting cases here:

Skipping RAR is extremely fast and appears to work in the first case, but it does produce some differences. For example, RAR produces @(ReferenceSatellitePaths) which is passed to GenerateDepsFile--which is presumably important.

@dsplaisted do you have a feel for whether that torpedos the skip-it-entirely-for-Core plan? I suspect it does but not with great confidence.

rainersigwald commented 7 years ago

Just had a phone call with @DamianEdwards @AndyGerlicher @nguerrera @dsplaisted @davidfowl and @livarcocc. Please add anything I don't note below.

tl;dr: we should explore the general caching plan from https://github.com/Microsoft/msbuild/issues/2015#issuecomment-303875723

140 of the references in the template MVC project I've been playing with come from the microsoft.netcore.app package. Several of us were surprised by this since we hoped that would reduce to just netstandard.dll (or at least much less).

We decided that just skipping RAR entirely wasn't a good idea because of the need to find associated files and concern about unknown consequences.

We thought about caching dependencies at a per-assembly granularity, but are concerned that it wouldn't actually be faster than reading them from a file.

There's existing code that attempts to stop walking dependencies when it encounters Framework assemblies, but it's not in use with NuGet-delivered references. We could potentially annotate (some?) references and trim the exploration from there. But that might not help, since NuGet gives RAR a flat list of dependencies, including all of the "framework" ones.

The primary scenario at the moment is an MVC project with .cs code churn (and static references). Invalidating the cache if a ProjectReference rebuilt seems acceptable, especially since reference assemblies should reduce churn on references in the not-too-distant future.

The caching would be (pseudocode):

if ( hash(inputList) == cache.inputHash ):
    foreach previousOutput in cache.previousOutputs:
        if ( lastWriteTime(previousOutput) >= cache.previousTimestamp ):
            return fullRAR(inputList)
    return cache.previousOutputs
return fullRAR(inputList)
ericstj commented 7 years ago

But that might not help, since NuGet gives RAR a flat list of dependencies, including all of the "framework" ones.

We could just as well deliver these via targets that nuget installs. That's similar to what we're doing elsewhere and the project-system is doing work to support that. Just to let you know that is on the table, and could be considered as additional work if it would help the first-build case.

rainersigwald commented 7 years ago

For awareness: in #2215 I backed out the read-assemblies-only-once part of #2192, because on full framework it caused locks to be held on files after returning from RAR. We plan to try to get a fixed version back in in the 15.3 timeframe.

xoofx commented 5 years ago

Hey, So I'm hitting the exact same problem with our compilation pipeline at Unity. We are typically providing our own .NET framework facades, along all the assemblies of the engine...etc., so that's roughly 90 assembly references in each csproj. With around 20 projects in a solution, and if nothing changed, each project having exactly the same set of references, the build will still take 6 seconds to complete (!). That's huge (for "nothing changed") The main reason is coming from ResolveAssemblyReference that is taking from 200ms to 250ms per project to resolve the assemblies. Worse is that all these assembly references have <Private>False</Private> so not sure what is the point of having ResolveAssemblyReference running over them...

Do you have any suggestion on how to workaround this? (I tried the trick "AdjustRAR" above by @rainersigwald but it doesn't compile after that, maybe something has changed in the target files since then...)

nguerrera commented 5 years ago

When you say you are providing your own assemblies, are you generating a bunch of reference items, acquiring them from nuget package assets, or something else?

If you are generating reference items, can you try adding ExternallyResolved=true metadata to them?

nguerrera commented 5 years ago

https://github.com/Microsoft/msbuild/pull/2716

xoofx commented 5 years ago

When you say you are providing your own assemblies, are you generating a bunch of reference items, acquiring them from nuget packahe assets, or sething else?

Yes, a bunch of <Reference>

xoofx commented 5 years ago

If you are generating reference items, can you try adding ExternallyResolved=true metadata to them?

Han, maybe exactly what I'm looking for, gonna try that, thanks 👍

xoofx commented 5 years ago

Ok, so using ExternallyResolved is actually helping to reducing the compilation to 3.2 seconds... with 1.2 seconds is spend for ResolveAssemblyReference, which is around 60ms per csproj. That still quite a lot. I haven't checked, but what is remaining that ResolveAssemblyReference has to do on these assembly references?

xoofx commented 5 years ago

From the profiling, I'm getting this now:

image

Couldn't the StateFile be cached in memory? It would save maybe half of the time for ResolveAssemblyReference so in my case, I have around 35 projects * 40ms is saving still almost 1.5 seconds per "nothing-changed" build

xoofx commented 5 years ago

The state file for each project is around 600 to 700Kb on the disk, so likely quite laborious to load, as I'm running everything inside the same process, it might not reflect how things are working with node reuse (not sure an inprocess cache would be relevant actually...)

nguerrera commented 5 years ago

Relevant: #3914, #3868

ccastanedaucf commented 5 years ago

The StateFile cache currently uses the .NET BinaryFormatter for serialization, which is slow and space-inefficient for large data sets. There's a PR in #3868 to change the backing serialization format that should dramatically improve the StateFile read times. There's a similar perf trace in there which shows it cutting the ResolveAssemblyReference time for a solution by about half.

nguerrera commented 5 years ago

@xoofx, curious why you are building everything single proc.

xoofx commented 5 years ago

@xoofx, curious why you are building everything single proc.

It's for testing. Running things with a regular msbuild doesn't bring any differences. Projects have many dependencies between them, so lots of them can't run concurrently... likely msbuild with nodereuse is actually fighting to build these projects. Also I measured that launching the msbuild exe from the command line on an empty projects takes a 500-800ms (on a single project), while running things in-proc in a loop goes down to 100-150ms (that's likely mostly AssemblyResolveReferences)

The StateFile cache currently uses the .NET BinaryFormatter for serialization, which is slow and space-inefficient for large data sets. There's a PR in #3868 to change the backing serialization format that should dramatically improve the StateFile read times. There's a similar perf trace in there which shows it cutting the ResolveAssemblyReference time for a solution by about half.

Great! Though, checking a simple ConsoleApp with new SDK and the cache file is only 80Kb, while AssemblyResolveReferences has all the SDK ref assemblies to reference... wondering why there is such a difference, maybe my setup is making something different (they are not SDK or regular TargetFrameworkDir files, but only <Reference>)... 700Kb for a dependency that doesn't bring much value for the assemblies listed is quite annoying (assemblies are not copied, the assembly list is not duplicated, there are no conflicts.... in the end they are just passed to csc as-is...etc.)

xoofx commented 5 years ago

Wondering if #3914 could help also to fine grained the granularity of the cache data to share them between projects. In my case, most of these 800KB per project are exactly the same and could be actually shared. Do you think that would be relevant?