* AppRouterController.cs: chore: 提取公共模块,和 Play 共享。包括
AppRouter,Json,日志等 * csharp-sdk.sln: * RTM.csproj: * Common.csproj: * HttpUtils.cs: * Tests.cs: * JsonExtensions.cs: * Storage.csproj: * JustTest.cs: * AppRouterTest.cs: * AppRouterState.cs: * ObjectTest.cs: * Common.Test.csproj: * Common.Test.csproj: * AppRouterTest.cs: * Storage.Test.csproj: * AVObjectController.cs:
parent
68a047ba1e
commit
f171cee759
|
@ -1,64 +0,0 @@
|
||||||
using System;
|
|
||||||
using System.Threading;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
using System.Net.Http;
|
|
||||||
using Newtonsoft.Json;
|
|
||||||
|
|
||||||
namespace LeanCloud.Storage.Internal {
|
|
||||||
public class AppRouterController {
|
|
||||||
private AppRouterState currentState;
|
|
||||||
|
|
||||||
private readonly SemaphoreSlim locker = new SemaphoreSlim(1);
|
|
||||||
|
|
||||||
public async Task<AppRouterState> Get(string appId) {
|
|
||||||
if (string.IsNullOrEmpty(appId)) {
|
|
||||||
throw new ArgumentNullException(nameof(appId));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (currentState != null && !currentState.IsExpired) {
|
|
||||||
return currentState;
|
|
||||||
}
|
|
||||||
|
|
||||||
await locker.WaitAsync();
|
|
||||||
try {
|
|
||||||
if (currentState == null) {
|
|
||||||
try {
|
|
||||||
currentState = await QueryAsync(appId);
|
|
||||||
} catch (Exception) {
|
|
||||||
currentState = AppRouterState.GetFallbackServers(appId);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return currentState;
|
|
||||||
} finally {
|
|
||||||
locker.Release();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async Task<AppRouterState> QueryAsync(string appId) {
|
|
||||||
Console.WriteLine("QueryAsync");
|
|
||||||
|
|
||||||
string url = string.Format("https://app-router.com/2/route?appId={0}", appId);
|
|
||||||
|
|
||||||
HttpClient client = new HttpClient();
|
|
||||||
HttpRequestMessage request = new HttpRequestMessage {
|
|
||||||
RequestUri = new Uri(url),
|
|
||||||
Method = HttpMethod.Get
|
|
||||||
};
|
|
||||||
|
|
||||||
HttpResponseMessage response = await client.SendAsync(request);
|
|
||||||
client.Dispose();
|
|
||||||
request.Dispose();
|
|
||||||
|
|
||||||
string content = await response.Content.ReadAsStringAsync();
|
|
||||||
response.Dispose();
|
|
||||||
|
|
||||||
AppRouterState state = JsonConvert.DeserializeObject<AppRouterState>(content);
|
|
||||||
state.Source = "router";
|
|
||||||
return state;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Clear() {
|
|
||||||
currentState = null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -0,0 +1,77 @@
|
||||||
|
using System;
|
||||||
|
using System.Threading;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using System.Net.Http;
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
|
||||||
|
namespace LeanCloud.Common {
|
||||||
|
public class AppRouterController {
|
||||||
|
private AppRouterState currentState;
|
||||||
|
|
||||||
|
private readonly SemaphoreSlim locker = new SemaphoreSlim(1);
|
||||||
|
|
||||||
|
public async Task<AppRouterState> Get(string appId) {
|
||||||
|
if (string.IsNullOrEmpty(appId)) {
|
||||||
|
throw new ArgumentNullException(nameof(appId));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (currentState != null && !currentState.IsExpired) {
|
||||||
|
return currentState;
|
||||||
|
}
|
||||||
|
|
||||||
|
await locker.WaitAsync();
|
||||||
|
try {
|
||||||
|
if (currentState == null) {
|
||||||
|
try {
|
||||||
|
currentState = await QueryAsync(appId);
|
||||||
|
} catch (Exception) {
|
||||||
|
currentState = AppRouterState.GetFallbackServers(appId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return currentState;
|
||||||
|
} finally {
|
||||||
|
locker.Release();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async Task<AppRouterState> QueryAsync(string appId) {
|
||||||
|
HttpClient client = null;
|
||||||
|
HttpRequestMessage request = null;
|
||||||
|
HttpResponseMessage response = null;
|
||||||
|
|
||||||
|
try {
|
||||||
|
string url = string.Format("https://app-router.com/2/route?appId={0}", appId);
|
||||||
|
|
||||||
|
client = new HttpClient();
|
||||||
|
request = new HttpRequestMessage {
|
||||||
|
RequestUri = new Uri(url),
|
||||||
|
Method = HttpMethod.Get
|
||||||
|
};
|
||||||
|
HttpUtils.PrintRequest(client, request);
|
||||||
|
|
||||||
|
response = await client.SendAsync(request);
|
||||||
|
string content = await response.Content.ReadAsStringAsync();
|
||||||
|
HttpUtils.PrintResponse(response);
|
||||||
|
|
||||||
|
AppRouterState state = JsonConvert.DeserializeObject<AppRouterState>(content);
|
||||||
|
state.Source = "router";
|
||||||
|
|
||||||
|
return state;
|
||||||
|
} finally {
|
||||||
|
if (client != null) {
|
||||||
|
client.Dispose();
|
||||||
|
}
|
||||||
|
if (request != null) {
|
||||||
|
request.Dispose();
|
||||||
|
}
|
||||||
|
if (response != null) {
|
||||||
|
response.Dispose();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Clear() {
|
||||||
|
currentState = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,7 +1,7 @@
|
||||||
using System;
|
using System;
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
|
|
||||||
namespace LeanCloud.Storage.Internal {
|
namespace LeanCloud.Common {
|
||||||
public class AppRouterState {
|
public class AppRouterState {
|
||||||
const string EAST_CHINA_SUFFIX = "-9Nh9j0Va";
|
const string EAST_CHINA_SUFFIX = "-9Nh9j0Va";
|
||||||
const string US_SUFFIX = "-MdYXbMMI";
|
const string US_SUFFIX = "-MdYXbMMI";
|
||||||
|
@ -93,6 +93,5 @@ namespace LeanCloud.Storage.Internal {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -0,0 +1,14 @@
|
||||||
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<TargetFramework>netstandard2.0</TargetFramework>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<PackageReference Include="Newtonsoft.Json" Version="12.0.2" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<Folder Include="Log\" />
|
||||||
|
<Folder Include="Http\" />
|
||||||
|
</ItemGroup>
|
||||||
|
</Project>
|
|
@ -0,0 +1,49 @@
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Net.Http;
|
||||||
|
|
||||||
|
namespace LeanCloud.Common {
|
||||||
|
public class HttpUtils {
|
||||||
|
public static void PrintRequest(HttpClient client, HttpRequestMessage request, string content = null) {
|
||||||
|
if (client == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (request == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
StringBuilder sb = new StringBuilder();
|
||||||
|
sb.AppendLine("=== HTTP Request Start ===");
|
||||||
|
sb.AppendLine($"URL: {request.RequestUri}");
|
||||||
|
sb.AppendLine($"Method: {request.Method}");
|
||||||
|
sb.AppendLine($"Headers: ");
|
||||||
|
foreach (var header in client.DefaultRequestHeaders) {
|
||||||
|
sb.AppendLine($"\t{header.Key}: {string.Join(",", header.Value.ToArray())}");
|
||||||
|
}
|
||||||
|
foreach (var header in request.Headers) {
|
||||||
|
sb.AppendLine($"\t{header.Key}: {string.Join(",", header.Value.ToArray())}");
|
||||||
|
}
|
||||||
|
if (request.Content != null) {
|
||||||
|
foreach (var header in request.Content.Headers) {
|
||||||
|
sb.AppendLine($"\t{header.Key}: {string.Join(",", header.Value.ToArray())}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!string.IsNullOrEmpty(content)) {
|
||||||
|
sb.AppendLine($"Content: {content}");
|
||||||
|
}
|
||||||
|
sb.AppendLine("=== HTTP Request End ===");
|
||||||
|
Logger.Debug(sb.ToString());
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void PrintResponse(HttpResponseMessage response, string content = null) {
|
||||||
|
StringBuilder sb = new StringBuilder();
|
||||||
|
sb.AppendLine("=== HTTP Response Start ===");
|
||||||
|
sb.AppendLine($"URL: {response.RequestMessage.RequestUri}");
|
||||||
|
sb.AppendLine($"Status Code: {response.StatusCode}");
|
||||||
|
if (!string.IsNullOrEmpty(content)) {
|
||||||
|
sb.AppendLine($"Content: {content}");
|
||||||
|
}
|
||||||
|
sb.AppendLine("=== HTTP Response End ===");
|
||||||
|
Logger.Debug(sb.ToString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,8 +1,7 @@
|
||||||
using System;
|
using Newtonsoft.Json;
|
||||||
using Newtonsoft.Json;
|
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
namespace LeanCloud.Storage.Internal {
|
namespace LeanCloud.Common {
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 为 Json 解析提供异步接口
|
/// 为 Json 解析提供异步接口
|
||||||
/// </summary>
|
/// </summary>
|
|
@ -2,6 +2,7 @@
|
||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<TargetFramework>netstandard2.0</TargetFramework>
|
<TargetFramework>netstandard2.0</TargetFramework>
|
||||||
|
<ReleaseVersion>0.1.0</ReleaseVersion>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
@ -9,7 +10,6 @@
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ProjectReference Include="..\..\Storage\Storage\Storage.csproj" />
|
<ProjectReference Include="..\..\Storage\Storage\Storage.csproj" />
|
||||||
<ProjectReference Include="..\..\AppRouter\AppRouter\AppRouter.csproj" />
|
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<None Remove="Internal\WebSocket\Unity\websocket-sharp.dll" />
|
<None Remove="Internal\WebSocket\Unity\websocket-sharp.dll" />
|
||||||
|
|
|
@ -6,11 +6,7 @@ namespace LeanCloud.Test {
|
||||||
public class AppRouterTest {
|
public class AppRouterTest {
|
||||||
[Test]
|
[Test]
|
||||||
public async Task GetServers() {
|
public async Task GetServers() {
|
||||||
var appRouter = new AppRouterController();
|
|
||||||
for (int i = 0; i < 1000; i++) {
|
|
||||||
var state = await appRouter.Get("BMYV4RKSTwo8WSqt8q9ezcWF-gzGzoHsz");
|
|
||||||
TestContext.Out.WriteLine(state.ApiServer);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,6 +27,16 @@ namespace LeanCloud.Test {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void Zip() {
|
||||||
|
List<int> l1 = new List<int> { 1, 2, 3, 4 };
|
||||||
|
List<int> l2 = new List<int> { 1, 1, 2 };
|
||||||
|
var l3 = l1.Zip(l2, (e1, e2) => $"{e1}-{e2}");
|
||||||
|
foreach (var e in l3) {
|
||||||
|
TestContext.Out.WriteLine($"{e}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void GenericType() {
|
public void GenericType() {
|
||||||
List<int> list = new List<int> { 1, 1, 2, 3, 5, 8 };
|
List<int> list = new List<int> { 1, 1, 2, 3, 5, 8 };
|
||||||
|
|
|
@ -167,11 +167,21 @@ namespace LeanCloud.Test {
|
||||||
List<AVObject> objList = new List<AVObject>();
|
List<AVObject> objList = new List<AVObject>();
|
||||||
for (int i = 0; i < 5; i++) {
|
for (int i = 0; i < 5; i++) {
|
||||||
AVObject obj = AVObject.Create("Foo");
|
AVObject obj = AVObject.Create("Foo");
|
||||||
|
obj.ACL = new AVACL {
|
||||||
|
PublicReadAccess = true,
|
||||||
|
PublicWriteAccess = i % 2 == 0
|
||||||
|
};
|
||||||
obj["content"] = "batch object";
|
obj["content"] = "batch object";
|
||||||
objList.Add(obj);
|
objList.Add(obj);
|
||||||
}
|
}
|
||||||
await objList.SaveAllAsync();
|
await objList.SaveAllAsync();
|
||||||
await AVObject.DeleteAllAsync(objList);
|
try {
|
||||||
|
await AVObject.DeleteAllAsync(objList);
|
||||||
|
} catch (AggregateException e) {
|
||||||
|
foreach (AVException ie in e.InnerExceptions) {
|
||||||
|
TestContext.Out.WriteLine($"{ie.Code} : {ie.Message}");
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
|
|
|
@ -16,6 +16,5 @@
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ProjectReference Include="..\Storage\Storage.csproj" />
|
<ProjectReference Include="..\Storage\Storage.csproj" />
|
||||||
<ProjectReference Include="..\..\AppRouter\AppRouter\AppRouter.csproj" />
|
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
</Project>
|
</Project>
|
||||||
|
|
|
@ -122,7 +122,7 @@ namespace LeanCloud.Storage.Internal {
|
||||||
return tasks;
|
return tasks;
|
||||||
}
|
}
|
||||||
|
|
||||||
private IList<Task<IDictionary<string, object>>> ExecuteBatchRequest(IList<AVCommand> requests,
|
private async Task<IList<Task<IDictionary<string, object>>>> ExecuteBatchRequest(IList<AVCommand> requests,
|
||||||
CancellationToken cancellationToken) {
|
CancellationToken cancellationToken) {
|
||||||
var tasks = new List<Task<IDictionary<string, object>>>();
|
var tasks = new List<Task<IDictionary<string, object>>>();
|
||||||
int batchSize = requests.Count;
|
int batchSize = requests.Count;
|
||||||
|
@ -151,26 +151,16 @@ namespace LeanCloud.Storage.Internal {
|
||||||
{ "requests", encodedRequests }
|
{ "requests", encodedRequests }
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
AVPlugins.Instance.CommandRunner.RunCommandAsync<IList<object>>(command, cancellationToken).ContinueWith(t => {
|
|
||||||
if (t.IsFaulted || t.IsCanceled) {
|
|
||||||
foreach (var tcs in tcss) {
|
|
||||||
if (t.IsFaulted) {
|
|
||||||
tcs.TrySetException(t.Exception);
|
|
||||||
} else if (t.IsCanceled) {
|
|
||||||
tcs.TrySetCanceled();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
var resultsArray = t.Result.Item2;
|
try {
|
||||||
|
var response = await AVPlugins.Instance.CommandRunner.RunCommandAsync<IList<object>>(command, cancellationToken);
|
||||||
|
var resultsArray = response.Item2;
|
||||||
int resultLength = resultsArray.Count;
|
int resultLength = resultsArray.Count;
|
||||||
if (resultLength != batchSize) {
|
if (resultLength != batchSize) {
|
||||||
foreach (var tcs in tcss) {
|
foreach (var tcs in tcss) {
|
||||||
tcs.TrySetException(new InvalidOperationException(
|
tcs.TrySetException(new InvalidOperationException(
|
||||||
"Batch command result count expected: " + batchSize + " but was: " + resultLength + "."));
|
"Batch command result count expected: " + batchSize + " but was: " + resultLength + "."));
|
||||||
}
|
}
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < batchSize; ++i) {
|
for (int i = 0; i < batchSize; ++i) {
|
||||||
|
@ -188,9 +178,11 @@ namespace LeanCloud.Storage.Internal {
|
||||||
"Invalid batch command response."));
|
"Invalid batch command response."));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
} catch (Exception e) {
|
||||||
|
foreach (var tcs in tcss) {
|
||||||
return tasks;
|
tcs.TrySetException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,6 +12,6 @@
|
||||||
<PackageReference Include="Newtonsoft.Json" Version="12.0.2" />
|
<PackageReference Include="Newtonsoft.Json" Version="12.0.2" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ProjectReference Include="..\..\AppRouter\AppRouter\AppRouter.csproj" />
|
<ProjectReference Include="..\..\Common\Common.csproj" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
</Project>
|
</Project>
|
||||||
|
|
|
@ -0,0 +1,45 @@
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using NUnit.Framework;
|
||||||
|
using LeanCloud.Common;
|
||||||
|
|
||||||
|
namespace Common.Test {
|
||||||
|
public class Tests {
|
||||||
|
static void Print(LogLevel level, string info) {
|
||||||
|
switch (level) {
|
||||||
|
case LogLevel.Debug:
|
||||||
|
TestContext.Out.WriteLine($"[DEBUG] {info}");
|
||||||
|
break;
|
||||||
|
case LogLevel.Warn:
|
||||||
|
TestContext.Out.WriteLine($"[WARNING] {info}");
|
||||||
|
break;
|
||||||
|
case LogLevel.Error:
|
||||||
|
TestContext.Out.WriteLine($"[ERROR] {info}");
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
TestContext.Out.WriteLine(info);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[SetUp]
|
||||||
|
public void SetUp() {
|
||||||
|
TestContext.Out.WriteLine("Set up");
|
||||||
|
Logger.LogDelegate += Print;
|
||||||
|
}
|
||||||
|
|
||||||
|
[TearDown]
|
||||||
|
public void TearDown() {
|
||||||
|
TestContext.Out.WriteLine("Tear down");
|
||||||
|
Logger.LogDelegate -= Print;
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public async Task AppRouter() {
|
||||||
|
var appRouter = new AppRouterController();
|
||||||
|
for (int i = 0; i < 100; i++) {
|
||||||
|
var state = await appRouter.Get("BMYV4RKSTwo8WSqt8q9ezcWF-gzGzoHsz");
|
||||||
|
TestContext.Out.WriteLine(state.ApiServer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,18 @@
|
||||||
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<TargetFramework>netcoreapp3.0</TargetFramework>
|
||||||
|
|
||||||
|
<IsPackable>false</IsPackable>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<PackageReference Include="nunit" Version="3.12.0" />
|
||||||
|
<PackageReference Include="NUnit3TestAdapter" Version="3.13.0" />
|
||||||
|
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.2.0" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<ProjectReference Include="..\..\Common\Common.csproj" />
|
||||||
|
</ItemGroup>
|
||||||
|
</Project>
|
|
@ -27,14 +27,16 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LiveQuery.Test", "LiveQuery
|
||||||
EndProject
|
EndProject
|
||||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Storage.Test", "Storage\Storage.Test\Storage.Test.csproj", "{BE05B492-78CD-47CA-9F48-C3E9B4813AFF}"
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Storage.Test", "Storage\Storage.Test\Storage.Test.csproj", "{BE05B492-78CD-47CA-9F48-C3E9B4813AFF}"
|
||||||
EndProject
|
EndProject
|
||||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "AppRouter", "AppRouter", "{1F05195D-2CAA-4214-8DAE-FE14A6B905DD}"
|
|
||||||
EndProject
|
|
||||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AppRouter", "AppRouter\AppRouter\AppRouter.csproj", "{D34FC092-042A-44CE-A9E2-56B996BDCF42}"
|
|
||||||
EndProject
|
|
||||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Storage", "Storage\Storage\Storage.csproj", "{59DA32A0-4CD3-424A-8584-D08B8D1E2B98}"
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Storage", "Storage\Storage\Storage.csproj", "{59DA32A0-4CD3-424A-8584-D08B8D1E2B98}"
|
||||||
EndProject
|
EndProject
|
||||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RTM", "RTM\RTM\RTM.csproj", "{D4A30F70-AAED-415D-B940-023B3D7241EE}"
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RTM", "RTM\RTM\RTM.csproj", "{D4A30F70-AAED-415D-B940-023B3D7241EE}"
|
||||||
EndProject
|
EndProject
|
||||||
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Common", "Common\Common.csproj", "{14EC150A-EF90-4E0B-B6D7-C2CF1945F6E5}"
|
||||||
|
EndProject
|
||||||
|
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Test", "Test", "{C827DA2F-6AB4-48D8-AB5B-6DAB925F8933}"
|
||||||
|
EndProject
|
||||||
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Common.Test", "Test\Common.Test\Common.Test.csproj", "{4DF4E0F4-1013-477F-ADA6-BFAFD9312335}"
|
||||||
|
EndProject
|
||||||
Global
|
Global
|
||||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
Debug|Any CPU = Debug|Any CPU
|
Debug|Any CPU = Debug|Any CPU
|
||||||
|
@ -77,10 +79,6 @@ Global
|
||||||
{BE05B492-78CD-47CA-9F48-C3E9B4813AFF}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
{BE05B492-78CD-47CA-9F48-C3E9B4813AFF}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
{BE05B492-78CD-47CA-9F48-C3E9B4813AFF}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
{BE05B492-78CD-47CA-9F48-C3E9B4813AFF}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
{BE05B492-78CD-47CA-9F48-C3E9B4813AFF}.Release|Any CPU.Build.0 = Release|Any CPU
|
{BE05B492-78CD-47CA-9F48-C3E9B4813AFF}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
{D34FC092-042A-44CE-A9E2-56B996BDCF42}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
|
||||||
{D34FC092-042A-44CE-A9E2-56B996BDCF42}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
|
||||||
{D34FC092-042A-44CE-A9E2-56B996BDCF42}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
|
||||||
{D34FC092-042A-44CE-A9E2-56B996BDCF42}.Release|Any CPU.Build.0 = Release|Any CPU
|
|
||||||
{59DA32A0-4CD3-424A-8584-D08B8D1E2B98}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
{59DA32A0-4CD3-424A-8584-D08B8D1E2B98}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
{59DA32A0-4CD3-424A-8584-D08B8D1E2B98}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
{59DA32A0-4CD3-424A-8584-D08B8D1E2B98}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
{59DA32A0-4CD3-424A-8584-D08B8D1E2B98}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
{59DA32A0-4CD3-424A-8584-D08B8D1E2B98}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
@ -89,6 +87,14 @@ Global
|
||||||
{D4A30F70-AAED-415D-B940-023B3D7241EE}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
{D4A30F70-AAED-415D-B940-023B3D7241EE}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
{D4A30F70-AAED-415D-B940-023B3D7241EE}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
{D4A30F70-AAED-415D-B940-023B3D7241EE}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
{D4A30F70-AAED-415D-B940-023B3D7241EE}.Release|Any CPU.Build.0 = Release|Any CPU
|
{D4A30F70-AAED-415D-B940-023B3D7241EE}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
{14EC150A-EF90-4E0B-B6D7-C2CF1945F6E5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
|
{14EC150A-EF90-4E0B-B6D7-C2CF1945F6E5}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{14EC150A-EF90-4E0B-B6D7-C2CF1945F6E5}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{14EC150A-EF90-4E0B-B6D7-C2CF1945F6E5}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
{4DF4E0F4-1013-477F-ADA6-BFAFD9312335}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
|
{4DF4E0F4-1013-477F-ADA6-BFAFD9312335}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{4DF4E0F4-1013-477F-ADA6-BFAFD9312335}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{4DF4E0F4-1013-477F-ADA6-BFAFD9312335}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(NestedProjects) = preSolution
|
GlobalSection(NestedProjects) = preSolution
|
||||||
{659D19F0-9A40-42C0-886C-555E64F16848} = {CD6B6669-1A56-437A-932E-BCE7F5D4CD18}
|
{659D19F0-9A40-42C0-886C-555E64F16848} = {CD6B6669-1A56-437A-932E-BCE7F5D4CD18}
|
||||||
|
@ -100,9 +106,9 @@ Global
|
||||||
{3251B4D8-D11A-4D90-8626-27FEE266B066} = {5B895B7A-1F6E-40A5-8081-43B334D2C076}
|
{3251B4D8-D11A-4D90-8626-27FEE266B066} = {5B895B7A-1F6E-40A5-8081-43B334D2C076}
|
||||||
{F907012C-74DF-4575-AFE6-E8DAACC26D24} = {5B895B7A-1F6E-40A5-8081-43B334D2C076}
|
{F907012C-74DF-4575-AFE6-E8DAACC26D24} = {5B895B7A-1F6E-40A5-8081-43B334D2C076}
|
||||||
{BE05B492-78CD-47CA-9F48-C3E9B4813AFF} = {CD6B6669-1A56-437A-932E-BCE7F5D4CD18}
|
{BE05B492-78CD-47CA-9F48-C3E9B4813AFF} = {CD6B6669-1A56-437A-932E-BCE7F5D4CD18}
|
||||||
{D34FC092-042A-44CE-A9E2-56B996BDCF42} = {1F05195D-2CAA-4214-8DAE-FE14A6B905DD}
|
|
||||||
{59DA32A0-4CD3-424A-8584-D08B8D1E2B98} = {CD6B6669-1A56-437A-932E-BCE7F5D4CD18}
|
{59DA32A0-4CD3-424A-8584-D08B8D1E2B98} = {CD6B6669-1A56-437A-932E-BCE7F5D4CD18}
|
||||||
{D4A30F70-AAED-415D-B940-023B3D7241EE} = {64D8F9A1-BA44-459C-817C-788B4EBC0B9F}
|
{D4A30F70-AAED-415D-B940-023B3D7241EE} = {64D8F9A1-BA44-459C-817C-788B4EBC0B9F}
|
||||||
|
{4DF4E0F4-1013-477F-ADA6-BFAFD9312335} = {C827DA2F-6AB4-48D8-AB5B-6DAB925F8933}
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(MonoDevelopProperties) = preSolution
|
GlobalSection(MonoDevelopProperties) = preSolution
|
||||||
version = 0.1.0
|
version = 0.1.0
|
||||||
|
|
Loading…
Reference in New Issue