migrate everything to netstandard1.5

pull/6104/head
Jan Tattermusch 9 years ago
parent 474a574ba7
commit 317b8acf99
  1. 8
      src/csharp/Grpc.Auth/project.json
  2. 2
      src/csharp/Grpc.Core.Tests/AppDomainUnloadTest.cs
  3. 2
      src/csharp/Grpc.Core.Tests/NUnitMain.cs
  4. 3
      src/csharp/Grpc.Core.Tests/SanityTest.cs
  5. 15
      src/csharp/Grpc.Core.Tests/project.json
  6. 2
      src/csharp/Grpc.Core/GrpcEnvironment.cs
  7. 4
      src/csharp/Grpc.Core/Internal/NativeExtension.cs
  8. 2
      src/csharp/Grpc.Core/Internal/PlatformApis.cs
  9. 17
      src/csharp/Grpc.Core/project.json
  10. 15
      src/csharp/Grpc.Examples.MathClient/project.json
  11. 15
      src/csharp/Grpc.Examples.MathServer/project.json
  12. 2
      src/csharp/Grpc.Examples.Tests/NUnitMain.cs
  13. 15
      src/csharp/Grpc.Examples.Tests/project.json
  14. 12
      src/csharp/Grpc.Examples/project.json
  15. 2
      src/csharp/Grpc.HealthCheck.Tests/NUnitMain.cs
  16. 15
      src/csharp/Grpc.HealthCheck.Tests/project.json
  17. 4
      src/csharp/Grpc.HealthCheck/project.json
  18. 19
      src/csharp/Grpc.IntegrationTesting.Client/project.json
  19. 19
      src/csharp/Grpc.IntegrationTesting.QpsWorker/project.json
  20. 19
      src/csharp/Grpc.IntegrationTesting.Server/project.json
  21. 12
      src/csharp/Grpc.IntegrationTesting/GeneratedClientTest.cs
  22. 1
      src/csharp/Grpc.IntegrationTesting/GeneratedServiceBaseTest.cs
  23. 32
      src/csharp/Grpc.IntegrationTesting/InteropClient.cs
  24. 21
      src/csharp/Grpc.IntegrationTesting/MetadataCredentialsTest.cs
  25. 2
      src/csharp/Grpc.IntegrationTesting/NUnitMain.cs
  26. 2
      src/csharp/Grpc.IntegrationTesting/TestCredentials.cs
  27. 34
      src/csharp/Grpc.IntegrationTesting/project.json

@ -18,14 +18,14 @@
},
"frameworks": {
"net45": { },
"dotnet54": {
"netstandard1.5": {
"imports": [
"net45"
],
"dependencies": {
"Microsoft.CSharp": "4.0.1-beta-23516",
"Microsoft.NETCore.Portable.Compatibility": "1.0.1-beta-23516",
"System.Threading.Tasks": "4.0.11-beta-23516"
"Microsoft.NETCore.Portable.Compatibility": "1.0.1-rc2-24027",
"NETStandard.Library": "1.5.0-rc2-24027",
"System.Threading.Tasks": "4.0.11-rc2-24027"
}
}
}

@ -40,7 +40,7 @@ namespace Grpc.Core.Tests
{
public class AppDomainUnloadTest
{
#if DOTNET5_4
#if NETSTANDARD1_5
[Test]
[Ignore("Not supported for CoreCLR")]
public void AppDomainUnloadHookCanCleanupAbandonedCall()

@ -49,7 +49,7 @@ namespace Grpc.Core.Tests
{
// Make logger immune to NUnit capturing stdout and stderr to workaround https://github.com/nunit/nunit/issues/1406.
GrpcEnvironment.SetLogger(new TextWriterLogger(Console.Error));
#if DOTNET5_4
#if NETSTANDARD1_5
return new AutoRun(typeof(NUnitMain).GetTypeInfo().Assembly).Execute(args, new ExtendedTextWrapper(Console.Out), Console.In);
#else
return new AutoRun().Execute(args);

@ -45,7 +45,8 @@ namespace Grpc.Core.Tests
{
public class SanityTest
{
#if !DOTNET5_4
// TODO: make sanity test work for CoreCLR as well
#if !NETSTANDARD1_5
/// <summary>
/// Because we depend on a native library, sometimes when things go wrong, the
/// entire NUnit test process crashes. To be able to track down problems better,

@ -10,23 +10,26 @@
"emitEntryPoint": true
},
"dependencies": {
"Grpc.Core": "0.14.0-anexperiment",
"Grpc.Core": {
"version": "0.0.1",
"taget": "project"
},
"Newtonsoft.Json": "8.0.3",
"NUnit": "3.2.0",
"NUnitLite": "3.2.0-*"
},
"frameworks": {
"net45": { },
"dotnet54": {
"netstandard1.5": {
"imports": [
"portable-net45"
],
"dependencies": {
"Microsoft.NETCore.App": {
"type": "platform",
"version": "1.0.0-rc2-23931"
}
"NETStandard.Library": "1.5.0-rc2-24027"
}
}
},
"runtimes": {
"win7-x64": { }
}
}

@ -353,7 +353,7 @@ namespace Grpc.Core
if (!hooksRegistered)
{
// TODO(jtattermusch): register shutdownhooks for CoreCLR as well
#if !DOTNET5_4
#if !NETSTANDARD1_5
AppDomain.CurrentDomain.ProcessExit += ShutdownHookHandler;
AppDomain.CurrentDomain.DomainUnload += ShutdownHookHandler;

@ -117,7 +117,7 @@ namespace Grpc.Core.Internal
private static string GetAssemblyPath()
{
var assembly = typeof(NativeExtension).GetTypeInfo().Assembly;
#if DOTNET5_4
#if NETSTANDARD1_5
// Assembly.EscapedCodeBase does not exist under CoreCLR, but assemblies imported from a nuget package
// don't seem to be shadowed by DNX-based projects at all.
return assembly.Location;
@ -136,7 +136,7 @@ namespace Grpc.Core.Internal
#endif
}
#if !DOTNET5_4
#if !NETSTANDARD1_5
private static bool IsFileUri(string uri)
{
return uri.ToLowerInvariant().StartsWith(Uri.UriSchemeFile);

@ -53,7 +53,7 @@ namespace Grpc.Core.Internal
static PlatformApis()
{
#if DOTNET5_4
#if NETSTANDARD1_5
isLinux = RuntimeInformation.IsOSPlatform(OSPlatform.Linux);
isMacOSX = RuntimeInformation.IsOSPlatform(OSPlatform.OSX);
isWindows = RuntimeInformation.IsOSPlatform(OSPlatform.Windows);

@ -30,24 +30,13 @@
},
"frameworks": {
"net45": { },
"dotnet54": {
"netstandard1.5": {
"imports": [
"portable-net45"
],
"dependencies": {
"Microsoft.CSharp": "4.0.1-beta-23516",
"System.Collections": "4.0.11-beta-23516",
"System.Collections.Concurrent": "4.0.11-beta-23516",
"System.Console": "4.0.0-beta-23516",
"System.Linq": "4.0.1-beta-23516",
"System.Threading": "4.0.11-beta-23516",
"System.Threading.Thread": "4.0.0-beta-23516",
"System.Reflection": "4.1.0-beta-23516",
"System.Text.Encoding": "4.0.11-beta-23516",
"System.Text.RegularExpressions": "4.0.11-beta-23516",
"System.IO": "4.0.11-beta-23516",
"System.IO.FileSystem": "4.0.1-beta-23516",
"System.Runtime.InteropServices.RuntimeInformation": "4.0.0-beta-23516"
"NETStandard.Library": "1.5.0-rc2-24027",
"System.Threading.Thread": "4.0.0-rc2-24027"
}
}
}

@ -10,20 +10,23 @@
"emitEntryPoint": true
},
"dependencies": {
"Grpc.Examples": "1.0.0"
"Grpc.Examples": {
"version": "1.0.0",
"taget": "project"
}
},
"frameworks": {
"net45": { },
"dotnet54": {
"netstandard1.5": {
"imports": [
"portable-net45"
],
"dependencies": {
"Microsoft.NETCore.App": {
"type": "platform",
"version": "1.0.0-rc2-23931"
}
"NETStandard.Library": "1.5.0-rc2-24027"
}
}
},
"runtimes": {
"win7-x64": { }
}
}

@ -10,20 +10,23 @@
"emitEntryPoint": true
},
"dependencies": {
"Grpc.Examples": "1.0.0"
"Grpc.Examples": {
"version": "1.0.0",
"taget": "project"
}
},
"frameworks": {
"net45": { },
"dotnet54": {
"netstandard1.5": {
"imports": [
"portable-net45"
],
"dependencies": {
"Microsoft.NETCore.App": {
"type": "platform",
"version": "1.0.0-rc2-23931"
}
"NETStandard.Library": "1.5.0-rc2-24027"
}
}
},
"runtimes": {
"win7-x64": { }
}
}

@ -49,7 +49,7 @@ namespace Grpc.Examples.Tests
{
// Make logger immune to NUnit capturing stdout and stderr to workaround https://github.com/nunit/nunit/issues/1406.
GrpcEnvironment.SetLogger(new TextWriterLogger(Console.Error));
#if DOTNET5_4
#if NETSTANDARD1_5
return new AutoRun(typeof(NUnitMain).GetTypeInfo().Assembly).Execute(args, new ExtendedTextWrapper(Console.Out), Console.In);
#else
return new AutoRun().Execute(args);

@ -10,22 +10,25 @@
"emitEntryPoint": true
},
"dependencies": {
"Grpc.Examples": "1.0.0",
"Grpc.Examples": {
"version": "1.0.0",
"taget": "project"
},
"NUnit": "3.2.0",
"NUnitLite": "3.2.0-*"
},
"frameworks": {
"net45": { },
"dotnet54": {
"netstandard1.5": {
"imports": [
"portable-net45"
],
"dependencies": {
"Microsoft.NETCore.App": {
"type": "platform",
"version": "1.0.0-rc2-23931"
}
"NETStandard.Library": "1.5.0-rc2-24027"
}
}
},
"runtimes": {
"win7-x64": { }
}
}

@ -4,7 +4,10 @@
},
"dependencies": {
"Grpc.Core": "0.0.1",
"Grpc.Core": {
"version": "0.0.1",
"taget": "project"
},
"Google.Protobuf": "3.0.0-beta3"
},
"frameworks": {
@ -14,15 +17,12 @@
"System.IO": ""
}
},
"dotnet54": {
"netstandard1.5": {
"imports": [
"portable-net45"
],
"dependencies": {
"Microsoft.NETCore.App": {
"type": "platform",
"version": "1.0.0-rc2-23931"
}
"NETStandard.Library": "1.5.0-rc2-24027"
}
}
}

@ -49,7 +49,7 @@ namespace Grpc.HealthCheck.Tests
{
// Make logger immune to NUnit capturing stdout and stderr to workaround https://github.com/nunit/nunit/issues/1406.
GrpcEnvironment.SetLogger(new TextWriterLogger(Console.Error));
#if DOTNET5_4
#if NETSTANDARD1_5
return new AutoRun(typeof(NUnitMain).GetTypeInfo().Assembly).Execute(args, new ExtendedTextWrapper(Console.Out), Console.In);
#else
return new AutoRun().Execute(args);

@ -10,22 +10,25 @@
"emitEntryPoint": true
},
"dependencies": {
"Grpc.HealthCheck": "0.0.1",
"Grpc.HealthCheck": {
"version": "0.0.1",
"taget": "project"
},
"NUnit": "3.2.0",
"NUnitLite": "3.2.0-*"
},
"frameworks": {
"net45": { },
"dotnet54": {
"netstandard1.5": {
"imports": [
"portable-net45"
],
"dependencies": {
"Microsoft.NETCore.App": {
"type": "platform",
"version": "1.0.0-rc2-23931"
}
"NETStandard.Library": "1.5.0-rc2-24027"
}
}
},
"runtimes": {
"win7-x64": { }
}
}

@ -26,12 +26,12 @@
"System.IO": ""
}
},
"dotnet54": {
"netstandard1.5": {
"imports": [
"portable-net45"
],
"dependencies": {
"Microsoft.CSharp": "4.0.1-beta-23516"
"NETStandard.Library": "1.5.0-rc2-24027"
}
}
}

@ -10,9 +10,24 @@
"emitEntryPoint": true
},
"dependencies": {
"Grpc.IntegrationTesting": "1.0.0"
"Grpc.IntegrationTesting": {
"version": "1.0.0",
"taget": "project"
}
},
"frameworks": {
"net45": { }
"net45": { },
"netstandard1.5": {
"imports": [
"portable-net45",
"net45"
],
"dependencies": {
"NETStandard.Library": "1.5.0-rc2-24027"
}
}
},
"runtimes": {
"win7-x64": { }
}
}

@ -10,9 +10,24 @@
"emitEntryPoint": true
},
"dependencies": {
"Grpc.IntegrationTesting": "1.0.0"
"Grpc.IntegrationTesting": {
"version": "1.0.0",
"taget": "project"
}
},
"frameworks": {
"net45": { }
"net45": { },
"netstandard1.5": {
"imports": [
"portable-net45",
"net45"
],
"dependencies": {
"NETStandard.Library": "1.5.0-rc2-24027"
}
}
},
"runtimes": {
"win7-x64": { }
}
}

@ -10,9 +10,24 @@
"emitEntryPoint": true
},
"dependencies": {
"Grpc.IntegrationTesting": "1.0.0"
"Grpc.IntegrationTesting": {
"version": "1.0.0",
"taget": "project"
}
},
"frameworks": {
"net45": { }
"net45": { },
"netstandard1.5": {
"imports": [
"portable-net45",
"net45"
],
"dependencies": {
"NETStandard.Library": "1.5.0-rc2-24027"
}
}
},
"runtimes": {
"win7-x64": { }
}
}

@ -40,7 +40,6 @@ using System.Threading.Tasks;
using Grpc.Core;
using Grpc.Core.Utils;
using Grpc.Testing;
using Moq;
using NUnit.Framework;
namespace Grpc.IntegrationTesting
@ -49,14 +48,16 @@ namespace Grpc.IntegrationTesting
{
TestService.TestServiceClient unimplementedClient = new UnimplementedTestServiceClient();
// TODO: replace Moq by some mocking library with CoreCLR support.
#if !NETSTANDARD1_5
[Test]
public void ExpandedParamOverloadCanBeMocked()
{
var expected = new SimpleResponse();
var mockClient = new Mock<TestService.TestServiceClient>();
var mockClient = new Moq.Mock<TestService.TestServiceClient>();
// mocking is relatively clumsy because one needs to specify value for all the optional params.
mockClient.Setup(m => m.UnaryCall(It.IsAny<SimpleRequest>(), null, null, CancellationToken.None)).Returns(expected);
mockClient.Setup(m => m.UnaryCall(Moq.It.IsAny<SimpleRequest>(), null, null, CancellationToken.None)).Returns(expected);
Assert.AreSame(expected, mockClient.Object.UnaryCall(new SimpleRequest()));
}
@ -66,11 +67,12 @@ namespace Grpc.IntegrationTesting
{
var expected = new SimpleResponse();
var mockClient = new Mock<TestService.TestServiceClient>();
mockClient.Setup(m => m.UnaryCall(It.IsAny<SimpleRequest>(), It.IsAny<CallOptions>())).Returns(expected);
var mockClient = new Moq.Mock<TestService.TestServiceClient>();
mockClient.Setup(m => m.UnaryCall(Moq.It.IsAny<SimpleRequest>(), Moq.It.IsAny<CallOptions>())).Returns(expected);
Assert.AreSame(expected, mockClient.Object.UnaryCall(new SimpleRequest(), new CallOptions()));
}
#endif
[Test]
public void DefaultMethodStubThrows_UnaryCall()

@ -40,7 +40,6 @@ using System.Threading.Tasks;
using Grpc.Core;
using Grpc.Core.Utils;
using Grpc.Testing;
using Moq;
using NUnit.Framework;
namespace Grpc.IntegrationTesting

@ -145,16 +145,26 @@ namespace Grpc.IntegrationTesting
if (options.TestCase == "jwt_token_creds")
{
#if !NETSTANDARD1_5
var googleCredential = await GoogleCredential.GetApplicationDefaultAsync();
Assert.IsTrue(googleCredential.IsCreateScopedRequired);
credentials = ChannelCredentials.Create(credentials, googleCredential.ToCallCredentials());
#else
// TODO(jtattermusch): implement this
throw new NotImplementedException("Not supported on CoreCLR yet");
#endif
}
if (options.TestCase == "compute_engine_creds")
{
#if !NETSTANDARD1_5
var googleCredential = await GoogleCredential.GetApplicationDefaultAsync();
Assert.IsFalse(googleCredential.IsCreateScopedRequired);
credentials = ChannelCredentials.Create(credentials, googleCredential.ToCallCredentials());
#else
// TODO(jtattermusch): implement this
throw new NotImplementedException("Not supported on CoreCLR yet");
#endif
}
return credentials;
}
@ -245,7 +255,7 @@ namespace Grpc.IntegrationTesting
{
Console.WriteLine("running client_streaming");
var bodySizes = new List<int> { 27182, 8, 1828, 45904 }.ConvertAll((size) => new StreamingInputCallRequest { Payload = CreateZerosPayload(size) });
var bodySizes = new List<int> { 27182, 8, 1828, 45904 }.Select((size) => new StreamingInputCallRequest { Payload = CreateZerosPayload(size) });
using (var call = client.StreamingInputCall())
{
@ -266,7 +276,7 @@ namespace Grpc.IntegrationTesting
var request = new StreamingOutputCallRequest
{
ResponseType = PayloadType.Compressable,
ResponseParameters = { bodySizes.ConvertAll((size) => new ResponseParameters { Size = size }) }
ResponseParameters = { bodySizes.Select((size) => new ResponseParameters { Size = size }) }
};
using (var call = client.StreamingOutputCall(request))
@ -276,7 +286,7 @@ namespace Grpc.IntegrationTesting
{
Assert.AreEqual(PayloadType.Compressable, res.Payload.Type);
}
CollectionAssert.AreEqual(bodySizes, responseList.ConvertAll((item) => item.Payload.Body.Length));
CollectionAssert.AreEqual(bodySizes, responseList.Select((item) => item.Payload.Body.Length));
}
Console.WriteLine("Passed!");
}
@ -398,6 +408,7 @@ namespace Grpc.IntegrationTesting
public static async Task RunOAuth2AuthTokenAsync(TestService.TestServiceClient client, string oauthScope)
{
#if !NETSTANDARD1_5
Console.WriteLine("running oauth2_auth_token");
ITokenAccess credential = (await GoogleCredential.GetApplicationDefaultAsync()).CreateScoped(new[] { oauthScope });
string oauth2Token = await credential.GetAccessTokenForRequestAsync();
@ -415,10 +426,15 @@ namespace Grpc.IntegrationTesting
Assert.True(oauthScope.Contains(response.OauthScope));
Assert.AreEqual(GetEmailFromServiceAccountFile(), response.Username);
Console.WriteLine("Passed!");
#else
// TODO(jtattermusch): implement this
throw new NotImplementedException("Not supported on CoreCLR yet");
#endif
}
public static async Task RunPerRpcCredsAsync(TestService.TestServiceClient client, string oauthScope)
{
#if !NETSTANDARD1_5
Console.WriteLine("running per_rpc_creds");
ITokenAccess googleCredential = await GoogleCredential.GetApplicationDefaultAsync();
@ -432,6 +448,10 @@ namespace Grpc.IntegrationTesting
Assert.AreEqual(GetEmailFromServiceAccountFile(), response.Username);
Console.WriteLine("Passed!");
#else
// TODO(jtattermusch): implement this
throw new NotImplementedException("Not supported on CoreCLR yet");
#endif
}
public static async Task RunCancelAfterBeginAsync(TestService.TestServiceClient client)
@ -626,13 +646,17 @@ namespace Grpc.IntegrationTesting
// extracts the client_email field from service account file used for auth test cases
private static string GetEmailFromServiceAccountFile()
{
#if !NETSTANDARD1_5
string keyFile = Environment.GetEnvironmentVariable("GOOGLE_APPLICATION_CREDENTIALS");
Assert.IsNotNull(keyFile);
var jobject = JObject.Parse(File.ReadAllText(keyFile));
string email = jobject.GetValue("client_email").Value<string>();
Assert.IsTrue(email.Length > 0); // spec requires nonempty client email.
return email;
#else
// TODO(jtattermusch): implement this
throw new NotImplementedException("Not supported on CoreCLR yet");
#endif
}
private static Metadata CreateTestMetadata()

@ -40,7 +40,6 @@ using System.Threading.Tasks;
using Grpc.Core;
using Grpc.Core.Utils;
using Grpc.Testing;
using Moq;
using NUnit.Framework;
namespace Grpc.IntegrationTesting
@ -52,19 +51,14 @@ namespace Grpc.IntegrationTesting
Channel channel;
TestService.TestServiceClient client;
List<ChannelOption> options;
Mock<TestService.TestServiceBase> serviceMock;
AsyncAuthInterceptor asyncAuthInterceptor;
[SetUp]
public void Init()
{
serviceMock = new Mock<TestService.TestServiceBase>();
serviceMock.Setup(m => m.UnaryCall(It.IsAny<SimpleRequest>(), It.IsAny<ServerCallContext>()))
.Returns(new Func<SimpleRequest, ServerCallContext, Task<SimpleResponse>>(UnaryCallHandler));
server = new Server
{
Services = { TestService.BindService(serviceMock.Object) },
Services = { TestService.BindService(new FakeTestService()) },
Ports = { { Host, ServerPort.PickUnused, TestCredentials.CreateSslServerCredentials() } }
};
server.Start();
@ -96,7 +90,7 @@ namespace Grpc.IntegrationTesting
channel = new Channel(Host, server.Ports.Single().BoundPort, channelCredentials, options);
client = TestService.NewClient(channel);
client.UnaryCall(new SimpleRequest {});
client.UnaryCall(new SimpleRequest { });
}
[Test]
@ -109,11 +103,14 @@ namespace Grpc.IntegrationTesting
client.UnaryCall(new SimpleRequest { }, new CallOptions(credentials: callCredentials));
}
private Task<SimpleResponse> UnaryCallHandler(SimpleRequest request, ServerCallContext context)
private class FakeTestService : TestService.TestServiceBase
{
var authToken = context.RequestHeaders.First((entry) => entry.Key == "authorization").Value;
Assert.AreEqual("SECRET_TOKEN", authToken);
return Task.FromResult(new SimpleResponse());
public override Task<SimpleResponse> UnaryCall(SimpleRequest request, ServerCallContext context)
{
var authToken = context.RequestHeaders.First((entry) => entry.Key == "authorization").Value;
Assert.AreEqual("SECRET_TOKEN", authToken);
return Task.FromResult(new SimpleResponse());
}
}
}
}

@ -49,7 +49,7 @@ namespace Grpc.IntegrationTesting
{
// Make logger immune to NUnit capturing stdout and stderr to workaround https://github.com/nunit/nunit/issues/1406.
GrpcEnvironment.SetLogger(new TextWriterLogger(Console.Error));
#if DOTNET5_4
#if NETSTANDARD1_5
return new AutoRun(typeof(NUnitMain).GetTypeInfo().Assembly).Execute(args, new ExtendedTextWrapper(Console.Out), Console.In);
#else
return new AutoRun().Execute(args);

@ -90,7 +90,7 @@ namespace Grpc.IntegrationTesting
private static string GetPath(string relativePath)
{
var assemblyDir = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
var assemblyDir = Path.GetDirectoryName(typeof(TestCredentials).GetTypeInfo().Assembly.Location);
return Path.Combine(assemblyDir, relativePath);
}
}

@ -1,23 +1,51 @@
{
"buildOptions": {
"compile": "**/*.cs",
"copyToOutput": {
"mappings": {
"nativelibs/windows_x64/grpc_csharp_ext.dll": "../../../vsprojects/x64/Debug/grpc_csharp_ext.dll",
"nativelibs/windows_x86/grpc_csharp_ext.dll": "../../../vsprojects/Debug/grpc_csharp_ext.dll"
},
"include": "data/*"
},
"emitEntryPoint": true
},
"dependencies": {
"Grpc.Auth": "0.0.1",
"Grpc.Core": "0.0.1",
"Grpc.Auth": {
"version": "0.0.1",
"taget": "project"
},
"Grpc.Core": {
"version": "0.0.1",
"taget": "project"
},
"Google.Protobuf": "3.0.0-beta3",
"CommandLineParser": "1.9.71",
"Moq": "4.2.1510.2205",
"NUnit": "3.2.0",
"NUnitLite": "3.2.0-*"
},
"frameworks": {
"net45": {
"dependencies": {
"Moq": "4.2.1510.2205"
},
"frameworkAssemblies": {
"System.Runtime": "",
"System.IO": ""
}
},
"netstandard1.5": {
"imports": [
"portable-net45",
"net45"
],
"dependencies": {
"NETStandard.Library": "1.5.0-rc2-24027",
"System.Linq.Expressions": "4.0.11-rc2-24027"
}
}
},
"runtimes": {
"win7-x64": { }
}
}

Loading…
Cancel
Save