Msbuild: ResolveAssemblyReference is slow on .NET Core with many references

Created on 26 Apr 2017  路  63Comments  路  Source: dotnet/msbuild

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

performance

Most helpful comment

Now that a few of these changes are in, I've taken some quick sample performance summaries building a couple .NET Core projects using the current tip of mater https://github.com/Microsoft/msbuild/commit/b630e674c729787d57a485ef5338915643eb1cea to show improvements we've made in RAR times since 15.9, although there's still plenty of room for improvement. These are all 3rd builds, incremental no-op. Included single-proc since multi-proc timings are added cumulatively across processes, but still useful to see.

MSBuild 15.9

WebLargeCore Single-Proc

Target Performance Summary:
    16923 ms  Build                                    130 calls

Task Performance Summary:
     5289 ms  ResolveAssemblyReference                 129 calls

WebLargeCore Multi-Proc

Target Performance Summary:
     6568 ms  Build                                    130 calls

Task Performance Summary:
     9855 ms  ResolveAssemblyReference                 129 calls

OrchardCore Single-Proc

Target Performance Summary:
    19573 ms  Build                                    133 calls

Task Performance Summary:
     6471 ms  ResolveAssemblyReference                 132 calls

OrchardCore Multi-Proc

Target Performance Summary:
     7888 ms  Build                                    133 calls

Task Performance Summary:
    13469 ms  ResolveAssemblyReference                 132 calls

MSBuild Master

WebLargeCore Single-Proc _(-44% RAR time)_

Target Performance Summary:
    13996 ms  Build                                    130 calls

Task Performance Summary:
     2976 ms  ResolveAssemblyReference                 129 calls

WebLargeCore Multi-Proc

Target Performance Summary:
     5329 ms  Build                                    130 calls

Task Performance Summary:
     6154 ms  ResolveAssemblyReference                 129 calls

OrchardCore Single-Proc _(-47% RAR time)_

Target Performance Summary:
    15618 ms  Build                                    133 calls

Task Performance Summary:
     3398 ms  ResolveAssemblyReference                 132 calls

OrchardCore Multi-Proc

Target Performance Summary:
     6039 ms  Build                                    133 calls

Task Performance Summary:
     7147 ms  ResolveAssemblyReference                 132 calls

All 63 comments

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.

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.

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

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.

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.

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

@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.

@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?

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

What other serialization options do we have?

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

@rainersigwald thanks

@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

@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

Or use this project if you want a really fun one 馃槅

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

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

  • A dotnet new mvc project passes 307 assemblies to RAR. That's a lot.
  • It also checks for the existence of ~5000 files.
  • Passing FindDependencies=false reduces overall time in RAR by ~half.
  • Profiling indicates no glaring hotspots, though there's plenty of room for improvement. Time is roughly evenly split between

    • I/O (reading files to get assembly versions, checking for existence)

    • RAR internals

    • Calling AssemblyName.Clone() via reflection (even after #2016)

  • Using full-framework MSBuild (with the existing caching strategy) improves performance significantly (~30%) but not enough.

There are a couple of options to shorten this:

  • Spend a ton of time improving perf.

    • Looking around, I think there are plenty of things that can be rewritten or cached in a static.

    • But probably not (say) a 10x speedup.

  • Build a total-inputs:total-outputs cache into RAR.

    • This is very hard in the general case, because arbitrary machine state not directly input to RAR can affect outputs: changing the registry, GACing files, installing a .NET SDK.

  • See if we can avoid calling RAR entirely.

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:

  • Find a file given a string.

    • But NuGet references are already resolved to an absolute path.

  • Find dependencies and satellite assemblies.

    • Should be described in the package.

  • Version unification and conflict resolution

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:

  • Are there situations where "the package paths are sufficient" aren't true? Can we detect them easily?
  • What metadata from RAR do we need to preserve (by teaching the NuGet package resolution logic about it)?

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

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?

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.

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

@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

@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

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?

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.

@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 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.

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).

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

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.

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

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?

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

Any update on this?

So my understanding is there are three interesting cases here:

  • .NET Core: assembly unification and binding redirects aren't interesting because of loader behavior.
  • .NET Framework DLLs: don't currently generate binding redirects
  • .NET Framework EXEs: generate binding redirects, so need the full rigamarole.

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.

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)

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.

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.

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...)

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?

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>

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 馃憤

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?

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

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...)

Relevant: #3914, #3868

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.

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

@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.)

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?

Currently #3914 works via a per-project cache of the full inputs/outputs of the task execution, but I've been toying with adding more granularity on cache-miss via keeping some of StateFile in memory within the RAR-service, and just skipping serialization all together in that case.

So I have JSonified the SystemState files and made a diff between the projects, extracting for example the diff between two assemblies that are the same:

image

So basically, it is almost the same information (minor difference here with culture info). So we have this repeated almost 90 times per project (one for each assembly), duplicated across 35 projects. 700Ko x 35 projects => 24Mo of data, that are actually the same in memory.

That's why I'm wondering why this could not be shared: having a global cache of data for all metadata for each assembly, and per project referencing those via a key... that would take a lot less spaces, reloading would be more efficient. You could store even per assembly information on the disk (via content based addressing objectid - ala git for example) and store minimal information per project then (list of assembly objectid )... @ccastanedaucf what do you think?

Note also that if you think in terms of CPU cache efficiency, sharing these assembly metadatas will make a significant difference when processing these references, considering that they take likely quite some spaces in memory, with many strings all around...

@xoofx Thanks for bringing this up; since #3868 may take some effort to get in since it adds some new dependencies (and doesn't solve the underlying problem of massive amounts of duplicated data), I've done some work in #3989 to distribute the data across projects and reduce the amount stored on disk and kept in memory.

@xoofx Thanks for bringing this up; since #3868 may take some effort to get in since it adds some new dependencies (and doesn't solve the underlying problem of massive amounts of duplicated data), I've done some work in #3989 to distribute the data across projects and reduce the amount stored on disk and kept in memory.

That's great, thanks for trying to implement the idea 馃憤

I'm going probably to continue investigating a bit more, ResolveAssemblyReferences is now around 40ms per project in my case, but this is still too much imo.

Now that a few of these changes are in, I've taken some quick sample performance summaries building a couple .NET Core projects using the current tip of mater https://github.com/Microsoft/msbuild/commit/b630e674c729787d57a485ef5338915643eb1cea to show improvements we've made in RAR times since 15.9, although there's still plenty of room for improvement. These are all 3rd builds, incremental no-op. Included single-proc since multi-proc timings are added cumulatively across processes, but still useful to see.

MSBuild 15.9

WebLargeCore Single-Proc

Target Performance Summary:
    16923 ms  Build                                    130 calls

Task Performance Summary:
     5289 ms  ResolveAssemblyReference                 129 calls

WebLargeCore Multi-Proc

Target Performance Summary:
     6568 ms  Build                                    130 calls

Task Performance Summary:
     9855 ms  ResolveAssemblyReference                 129 calls

OrchardCore Single-Proc

Target Performance Summary:
    19573 ms  Build                                    133 calls

Task Performance Summary:
     6471 ms  ResolveAssemblyReference                 132 calls

OrchardCore Multi-Proc

Target Performance Summary:
     7888 ms  Build                                    133 calls

Task Performance Summary:
    13469 ms  ResolveAssemblyReference                 132 calls

MSBuild Master

WebLargeCore Single-Proc _(-44% RAR time)_

Target Performance Summary:
    13996 ms  Build                                    130 calls

Task Performance Summary:
     2976 ms  ResolveAssemblyReference                 129 calls

WebLargeCore Multi-Proc

Target Performance Summary:
     5329 ms  Build                                    130 calls

Task Performance Summary:
     6154 ms  ResolveAssemblyReference                 129 calls

OrchardCore Single-Proc _(-47% RAR time)_

Target Performance Summary:
    15618 ms  Build                                    133 calls

Task Performance Summary:
     3398 ms  ResolveAssemblyReference                 132 calls

OrchardCore Multi-Proc

Target Performance Summary:
     6039 ms  Build                                    133 calls

Task Performance Summary:
     7147 ms  ResolveAssemblyReference                 132 calls

I think if NuGet implemented https://github.com/NuGet/Home/issues/7617, some global targets provided by them could hook into that and do that per-nuget immutability caching/optimization at restore time, ideally only once, without having MSBuild know anything about how that's done. For example, they could emit additional obj targets (but in the package install path, rather than the user's obj, since they would be immutable for a given package), so that even Rebuild would benefit from it.

It would also allow package authors to extend the same mechanism, as explained in that issue.

@kzu I don't think I'm seeing the connection between that comment and RAR performance; can you elaborate?

@rainersigwald basically, do what was suggested only once and at restore time:

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.

;). That part could leverage the same extension point for AfterRestore proposed in that issue.

I see. I don't think that's a viable option here because RAR needs to see all references in order to do version unification and generate binding redirects, and the inputs to that could change outside of Restore (via Reference item changes or transitive reference changes from ProjectReferences).

microsoft/msbuild#3868 has a good perf improvement in RAR cache serialization, but we're not sure the Bond serialization is the best approach. We should consider reviving it at some point in the future.

we're not sure the Bond serialization is the best approach.

What are the downsides of it? Have you explored other alternatives?

@ladipro, heads up on this one. We should link it to our RAR user story.

Was this page helpful?
0 / 5 - 0 ratings