Created
January 6, 2018 13:17
-
-
Save raveneer/0add786e71ce93761d65132563179d5c to your computer and use it in GitHub Desktop.
클래스명을 알고 있는 임의의 클래스를 Json을 이용해서 직렬/역직렬화 하는 클래스. Json.Net을 사용한다.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Diagnostics; | |
using Newtonsoft.Json; | |
using NUnit.Framework; | |
namespace UnitTestProject | |
{ | |
internal class Test_ComponentGenerator | |
{ | |
[Test] | |
public void MakeNewComponentWithJson_1() | |
{ | |
var jsonString = @"{""TypeName"":""UnitTestProject.SomeDog"",""Json"":""{\""BitePower\"":10.0}""}"; | |
var newComponent = AnonymousClassJsonParser.MakeNewClassOrNull(jsonString); | |
Assert.IsTrue(newComponent is SomeDog); | |
Assert.AreEqual(10, ((SomeDog) newComponent).BitePower); | |
} | |
[Test] | |
public void MakeNewComponentWithJson_2() | |
{ | |
var jsonString = @"{""TypeName"":""UnitTestProject.SomeCat"",""Json"":""{\""ScratchPower\"":5.0}""}"; | |
var newComponent = AnonymousClassJsonParser.MakeNewClassOrNull(jsonString); | |
Assert.IsTrue(newComponent is SomeCat); | |
Assert.AreEqual(5, ((SomeCat) newComponent).ScratchPower); | |
} | |
[Test] | |
public void MakeNestedJsonFromIComponent() | |
{ | |
var fido = new SomeDog {BitePower = 10}; | |
var json = AnonymousClassJsonParser.MakeNestedJson(fido); | |
var expected = @"{""TypeName"":""UnitTestProject.SomeDog"",""Json"":""{\""BitePower\"":10.0}""}"; | |
Assert.AreEqual(expected, json); | |
} | |
[Test] | |
public void SelialAndDeselial() | |
{ | |
var fido = new SomeDog {BitePower = 10}; | |
var jsonString = AnonymousClassJsonParser.MakeNestedJson(fido); | |
var newComponent = AnonymousClassJsonParser.MakeNewClassOrNull(jsonString); | |
Assert.AreEqual(fido.GetType(), newComponent.GetType()); | |
Assert.AreEqual(fido.BitePower, ((SomeDog) newComponent).BitePower); | |
} | |
[Timeout(500)] | |
[Test] | |
[Ignore("1만개에 500ms 정도로 매우 빠름.")] | |
public void Performance_Serialize() | |
{ | |
var fido = new SomeDog {BitePower = 10}; | |
for (var i = 0; i < 10000; i++) | |
{ | |
var jsonString = AnonymousClassJsonParser.MakeNestedJson(fido); | |
} | |
} | |
[Timeout(300)] | |
[Test] | |
[Ignore("1만개에 300ms 정도로 매우 빠름.")] | |
public void Performance_DeSerialize() | |
{ | |
var jsonString = @"{""TypeName"":""UnitTestProject.SomeCat"",""Json"":""{\""ScratchPower\"":5.0}""}"; | |
for (var i = 0; i < 10000; i++) | |
{ | |
var newComponent = AnonymousClassJsonParser.MakeNewClassOrNull(jsonString); | |
Assert.IsTrue(newComponent is SomeCat); | |
} | |
} | |
[Test] | |
public void MakeNewComponentWithJson_ReturnNull_NotMatchClassName() | |
{ | |
var jsonString = @"{""TypeName"":""blah"",""Json"":""{\""BitePower\"":10.0}""}"; | |
var newComponent = AnonymousClassJsonParser.MakeNewClassOrNull(jsonString); | |
Assert.IsNull(newComponent); | |
} | |
} | |
/// <summary> | |
/// json.net 을 사용함. 객체를 래퍼로 래핑하여 타입과 json 정보를 함께 저장한다. | |
/// 리플렉션을 이용하여 클래스를 만든다. 따라서 클래스 타입이 어셈블리에 있다면 생성되고 없으면 실패한다. | |
/// 주의 : IOS에서 작동여부가 불확실하다. 테스트 필요. | |
/// </summary> | |
public class AnonymousClassJsonParser | |
{ | |
public static object MakeNewClassOrNull(string nestedJson) | |
{ | |
if (string.IsNullOrWhiteSpace(nestedJson)) | |
{ | |
return null; | |
} | |
var wrapper = JsonConvert.DeserializeObject<TypeWrapper>(nestedJson); | |
if (string.IsNullOrWhiteSpace(wrapper.TypeName)) | |
{ | |
return null; | |
} | |
try | |
{ | |
var classType = Type.GetType(wrapper.TypeName, true); | |
return JsonConvert.DeserializeObject(wrapper.Json, classType); | |
} | |
catch (Exception e) | |
{ | |
Debug.WriteLine(e.Message); | |
return null; | |
} | |
} | |
public static string MakeNestedJson(object obj) | |
{ | |
var wrapper = new TypeWrapper | |
{ | |
TypeName = obj.GetType().ToString(), | |
Json = JsonConvert.SerializeObject(obj) | |
}; | |
return JsonConvert.SerializeObject(wrapper); | |
} | |
public class TypeWrapper | |
{ | |
public string TypeName; | |
public string Json; | |
} | |
} | |
public class SomeDog | |
{ | |
public float BitePower = 10; | |
} | |
public class SomeCat | |
{ | |
public float ScratchPower = 0; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment