2015-02-13 13 views
6

Praca z aplikacją ASP.NET 5 (Visual Studio 2015 CTP5) i Microsoft.CodeAnalysis.CSharp.Roslyn - Utwórz metadaneReferencja z zestawu w pamięci

Jeśli próbuję utworzyć metadanychReference do zespołu, który jest częścią rozwiązania, aby przekazać go jako odniesienie do CSharpCompilation.Create, otrzymuję System.ArgumentException, "Pusta nazwa ścieżki nie jest legalna".

Jeśli sprawdzę właściwość Lokalizacja zestawu, jest on pusty. Zakładam, że jest to związane z nowym sposobem kompilowania aplikacji w pamięci w ASP.NET 5, dzięki czemu zestaw nie jest przechowywany na dysku.

Czy istnieje sposób przekazania odniesienia do Roslyn dla Zgromadzenia bez właściwości Lokalizacja lub czy jest to obecnie nieobsługiwane?

EDYTOWANIE: @JaredPar - @SLaks podświetlił dokładnie, gdzie się nie udało, ale tutaj znajduje się pełna informacja o stosie. Tworzę kilka innych MetadataReferences z zestawów System. * I nie ma problemu z żadnym z nich.

System.ArgumentException 
Empty path name is not legal. 
C:\Development\Incubator\net.framework\src\Webfuel.Services.Host\ScriptHelper\ScriptHelper.cs 
Line 86: 
Line 87:    // Compile the code 
Line 88:    var compilation = CSharpCompilation.Create(
Line 89:     assemblyName, 
Line 90:     options: new CSharpCompilationOptions(outputKind: OutputKind.DynamicallyLinkedLibrary), 
at System.IO.FileStream.Init(String path, FileMode mode, FileAccess access, Int32 rights, Boolean useRights, FileShare share, Int32 bufferSize, FileOptions options, Win32Native.SECURITY_ATTRIBUTES secAttrs, String msgPath, Boolean bFromProxy, Boolean useLongPath, Boolean checkHost) 
at System.IO.FileStream..ctor(String path, FileMode mode, FileAccess access, FileShare share) 
at System.IO.File.OpenRead(String path) 
at Microsoft.CodeAnalysis.InternalUtilities.FileStreamLightUp.OpenFileStream(String path) 
at Microsoft.CodeAnalysis.MetadataReference.CreateFromAssembly(Assembly assembly, MetadataReferenceProperties properties, DocumentationProvider documentation) 
at Microsoft.CodeAnalysis.MetadataReference.CreateFromAssembly(Assembly assembly) 
at Webfuel.Services.Host.ScriptHelper.CompileScriptImpl(String source) in C:\Development\Incubator\net.framework\src\Webfuel.Services.Host\ScriptHelper\ScriptHelper.cs:line 88 
at Webfuel.Services.Host.ScriptHelper.<>c__DisplayClass0.<CompileTemplate>b__3(String source) in C:\Development\Incubator\net.framework\src\Webfuel.Services.Host\ScriptHelper\ScriptHelper.cs:line 71 
at System.Collections.Concurrent.ConcurrentDictionary<TKey, TValue>.GetOrAdd(TKey key, Func<TKey, TValue> valueFactory) 
at Webfuel.Services.Host.ScriptHelper.CompileTemplate(String template) in C:\Development\Incubator\net.framework\src\Webfuel.Services.Host\ScriptHelper\ScriptHelper.cs:line 69 
at Webfuel.Services.Host.SandboxContext.<ExecuteTemplateAsync>d__1.MoveNext() in C:\Development\Incubator\net.framework\src\Webfuel.Services.Host\SandboxContext.cs:line 176 
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) 
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) 
at System.Runtime.CompilerServices.TaskAwaiter<TResult>.GetResult() 
at Webfuel.Services.Host.SandboxHost.<ExecuteTemplateAsync>d__1.MoveNext() in C:\Development\Incubator\net.framework\src\Webfuel.Services.Host\SandboxHost.cs:line 39 
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) 
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) 
at System.Runtime.CompilerServices.TaskAwaiter<TResult>.GetResult() 
at Webfuel.Services.Sandbox.SandboxService.<ExecuteTemplateAsync>d__1.MoveNext() in C:\Development\Incubator\net.framework\src\Webfuel.Services.Sandbox\SandboxService.cs:line 47 
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) 
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) 
at System.Runtime.CompilerServices.TaskAwaiter<TResult>.GetResult() 
at Webfuel.Services.Server.ServerService.<ProcessContentRequestAsync>d__1.MoveNext() in C:\Development\Incubator\net.framework\src\Webfuel.Services.Server\ServerService.cs:line 179 
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) 
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) 
at System.Runtime.CompilerServices.TaskAwaiter<TResult>.GetResult() 
at Webfuel.Services.Server.ServerService.<ProcessRequestAsync>d__1.MoveNext() in C:\Development\Incubator\net.framework\src\Webfuel.Services.Server\ServerService.cs:line 73 
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) 
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) 
at System.Runtime.CompilerServices.TaskAwaiter<TResult>.GetResult() 
at Webfuel.App.ServerMiddleware.<Invoke>d__1.MoveNext() in C:\Development\Incubator\net.framework\src\Webfuel.App\Startup.cs:line 89 
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) 
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) 
at System.Runtime.CompilerServices.TaskAwaiter.GetResult() 
at Microsoft.AspNet.RequestContainer.ContainerMiddleware.<Invoke>d__1.MoveNext() 
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) 
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) 
at System.Runtime.CompilerServices.TaskAwaiter.GetResult() 
at Microsoft.AspNet.Loader.IIS.KlrHttpApplication.<ProcessRequestAsyncImpl>d__1.MoveNext() 
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) 
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) 
at System.Runtime.CompilerServices.TaskAwaiter.GetResult() 
at Microsoft.AspNet.Loader.IIS.HttpApplicationBase.<InvokeProcessRequestAsyncImpl>d__1.MoveNext() 
+0

Czy można dodać cały ślad stosu błędu? Pomoże to zrozumieć, dlaczego to się nie udało. – JaredPar

+0

@JaredPar: http://source.roslyn.io/#Microsoft.CodeAnalysis/MetadataReference/MetadataReference.cs, 297 – SLaks

Odpowiedz

3

Minęło trochę czasu, ale zrobiłem uzyskać odpowiedź na to repozytorium GitHub Roslyn więc wyślę go w przypadku gdy ktoś znajdzie na to pytanie:

ASP.NET 5 posiada interfejs API dla tego produktu. Można robić to, co robi Razor https://github.com/aspnet/Mvc/blob/dev/src/Microsoft.AspNet.Mvc.Razor/Compilation/RoslynCompilationService.cs#L132

To był z powrotem w okolice Beta1 programu ASP.NET 5 więc może wymagać szczypanie, ale zasada jest wciąż ten sam - postępować zgodnie z API, które sama Asp.Net używa poprzez IAssemblyLoadContextAccessor którym wtryskiwacz serwis zapewni.

Dzięki David Fowler

UPDATE: Ta odpowiedź była dla ASP.NET 5 Beta1. API nie zmieniło się wiele, aw Rdzenia 1,0 zamiast korzystania IAssemblyLoadContextAccessor, można uzyskać dostęp AssemblyLoadContext od członu statycznego:

System.Runtime.Loader.AssemblyLoadContext.Default 

a następnie można nazwać LoadFromStream załadować zespół z obrazu binarnego. Tutaj jest bardzo szorstki szkic kodu korzystam z pewnymi nieistotnymi bitów zaatakowanych się:

 // Give the assembly a unique name 
     var assemblyName = "Gen" + Guid.NewGuid().ToString().Replace("-", "") + ".dll"; 

     // Build the syntax tree 
     var syntaxTree = CSharpSyntaxTree.ParseText(source); 

     // Compile the code 
     var compilation = CSharpCompilation.Create(
      assemblyName, 
      options: new CSharpCompilationOptions(outputKind: OutputKind.DynamicallyLinkedLibrary), 
      syntaxTrees: new List<SyntaxTree> { syntaxTree }, 
      references: GetMetadataReferences()); 

     // Emit the image of this assembly 
     byte[] image = null; 
     using (var ms = new MemoryStream()) 
     { 
      var emitResult = compilation.Emit(ms); 
      if (!emitResult.Success) 
      { 
       throw new InvalidOperationException(); 
      } 
      image = ms.ToArray(); 
     } 

     Assembly assembly = null; 

     // NETCORE 
     using (var stream = new MemoryStream(image)) 
      assembly = System.Runtime.Loader.AssemblyLoadContext.Default.LoadFromStream(stream); 

Nie ma działać jak jest, ale tylko dać wyobrażenie o głównych etapach.

Problem z generowaniem odniesień do metadanych z zespołu tylko w pamięci już nie istnieje, ponieważ te nie istnieją już w wersji Core 1.0, więc każde Zgromadzenie ma właściwość Lokalizacja. Uzyskanie tych referencji jest w zasadzie tym samym procesem, co w ASP.net 4:

MetadataReference.CreateFromFile(Assembly.Load(new AssemblyName(assemblyName)).Location); 
0

Twoje pytanie jest niejasne.

Jeśli w zbiorze znajdują się bajty skompilowanego zestawu, zadzwoń pod numer MetadataReference.CreateFromImage().

Jeśli chcesz dodać odniesienie do projektu Roslyn w tym samym obszarze roboczym, zadzwoń pod numer Compilation.ToMetadataReference().

+1

Nie mam bajtów. Mam tylko odniesienie do zespołu (tj. Odwołanie do obiektu System.Reflection.Assembly). Ale zespół nie ma właściwości Location (jest pusta). –

+0

Jaki to rodzaj montażu? Z czego to pochodzi? – SLaks

+0

Jest to aplikacja ASP.NET 5 (nowy system projektowy w VS2015). Właśnie dostaję to przez typeof () .Assembly. Myślę, że ponieważ nowy system kompilacji nie pisze na dysk, to właśnie go łamie. Próbowałem ustawić ustawienie "Produce outputs on build" na ustawieniach projektu, ale to też nie pomogło. –

Powiązane problemy