
ãã€ãŠãç§ã®ååã¯ããã¯ãã°ã¿ã¹ã¯ã«é¥ããŸããããå
éšREST-apiãšã®å¯Ÿè©±ãæŽçããŠãå¥çŽã®å€æŽãããã«ã³ã³ãã€ã«ãšã©ãŒã«ã€ãªããããã«ããŸããã äœããã£ãšç°¡åã ãããïŒ -ããããçµæã®ãµããã³ã䜿ã£ãŠäœæ¥ããããšã§ã.Net Coreã«ç§»è¡ããŠäžéã¢ã»ã³ãã©ã®æåã³ãŒãçæãšæ°ããã³ã³ãã€ã©ã®åŠç¿ãè¡ãåã«ãããã¥ã¡ã³ããåžãããšãäœåãªããããŸããã CïŒ å人çã«ã¯ãã©ã³ã¿ã€ã ãšã³ã³ãã€ã©ãŒèªäœã®æ§é ã®äž¡æ¹ã§ãå€ãã®è峿·±ãããšãçºèŠããŸããã ããããã¹ã¯ã®äœæ°ããã§ã«ç¥ã£ãŠããããšãããã°ãæèã«åœ¹ç«ã€é£ã¹ç©ããããšæããŸãã
第1å¹ïŒã³ããŒïŒããŒã¹ã
ããã¯æ®éã®å
žåçãªã¿ã¹ã¯ã§ãããç§ã®å人ã¯ãã§ã«æãããªããšã«ã€ããŠé·ãéèãããããªãã£ããããçµæã¯éåžžã«æ©ãçŸããŸããã WCFã§ã¯RESTãµãŒãã¹ãç§ãã¡ã®ãã®ã§ãã£ãããããµãŒãã¹ã€ã³ã¿ãŒãã§ãŒã¹ãç§»è¡ãããäžè¬çãªã¢ã»ã³ããªMyProj.Abstracitons
ãå°å
¥ãããŸããã ãã®äžã§ããµãŒãã¹ã€ã³ã¿ãŒãã§ãŒã¹ãå®è£
ãããªã¯ãšã¹ãããããã·ããçµæããã·ãªã¢ã©ã€ãºããã¯ã©ã¹ã«æžã蟌ãå¿
èŠããããŸããã ã¢ã€ãã¢ã¯åçŽã§ãããåãã€ã³ã¿ãŒãã§ã€ã¹ãå®è£
ããã¯ã©ã€ã¢ã³ãã§ããããã®ãµãŒãã¹ãèšè¿°ãããšããµãŒãã¹ã®ã¡ãœããã倿Žãããšããã«ãã³ã³ãã€ã«ãšã©ãŒããããã¢ããããŸãã ãããŠã颿°ã®åŒæ°ã倿Žãã人ã¯ããããæ£ããã·ãªã¢ã«åãããŠããããšã確èªãããšä»®å®ããŸãã æ¬¡ã®ããã«ãªããŸããã
public class FooClient : BaseClient<IFooService> { private static readonly Uri _baseSubUri public FooClient() : base(BaseUri, _baseSubUri, LogManager.GetCurrentClassLogger()) {} [MethodImpl(MethodImplOptions.NoInlining)] public Task<Foo> GetFoo(int a, DateTime b, double c) { return GetFoo<Foo>(new Dictionary<string, object>{ {âaâ, a}, {âbâ, b.ToString(SerializationConstant.DateTimeFormat)}}, new Dictionary<string, object>{ {âcâ, c.ToString(SerializationConstant.FloatFormat)}}); } }
BaseClient<TService>
ã¯ã HttpClient
ãããªèãã©ãããŒã§ãåŒã³åºãã¡ãœããïŒãã®å Žåã¯GetFoo
ïŒã決å®ãããã®URLãèšç®ãããªã¯ãšã¹ããéä¿¡ããåçãGetFoo
ããçµæããã·ãªã¢ã©ã€ãºïŒå¿
èŠã«å¿ããŠïŒããŠæž¡ããŸãã
ããã¯ïŒ
BaseClient<TService>
ãç¶æ¿- ãã¹ãŠã®ã¡ãœãããå®è£
ããŸã
- ç§ãã¡ã¯ãã¹ãŠã®è°è«ã®ããã«ã©ãã§ãèŸæžãæžããŸãã
ååãšããŠãé£ããã¯ãªãã NoInlining
ããã30幎çã®20çªç®ã®ã¡ãœãããæžããåŸããŸã£ããåãã¿ã€ãã§ãããã人ã
ã¯åžžã«NoInlining
ãæžãã®ãå¿ããŠãNoInlining
ããã®ããããã¹ãŠãå£ããŸããïŒå°ããªã¯ã€ãºïŒ1ïŒãªãã ãšæããŸããïŒïŒç§ã¯èªåèªèº«ã«è³ªåãããŸããïŒãã©ãã«ãããŠäººéã«ããã«è¿ã¥ãããšã¯å¯èœã§ããïŒãã ããããã¿ã¹ã¯ã¯æ¢ã«ãã¹ã¿ãŒã«ããŒãžãããŠãããäžããããŽããåºããã«æ©èœã飲ãã ããšèšãããŸããã ããããç§ã¯ããããçš®é¡ã®ã©ãããŒãæžãã®ã«1æ¥3æéãè²»ãããšããèãã奜ãã§ã¯ãããŸããã§ããã äžé£ã®å±æ§ã¯èšããŸã§ããããŸãããã人ã
ã¯å®æçã«ã·ãªã¢ã«åãèªåã®å€æŽããã®ãããªçã¿ãšåæãããããšãå¿ããŠããŸããã ãããã£ãŠã次ã®é±æ«ã«å°éããç¶æ³ãäœããã®åœ¢ã§æ¹åããããã«çæããæ°æ¥éã圌ã¯ä»£æ¿ãœãªã¥ãŒã·ã§ã³ãã¹ã±ããããŸããã
第2å¹ïŒåå°
ããã§ã®ã¢ã€ãã¢ã¯ããã«ã·ã³ãã«ã§ãããåãããšãããããšãç§ãã¡ã劚ããŠããã®ã¯ãæã§ã¯ãªãåçã«çæããŠããã®ã§ããããïŒ å®å
šã«åäžã®ã¿ã¹ã¯ããããŸããå
¥ååŒæ°ãååŸããããããqueryStringåŒæ°çšã®2ã€ã®èŸæžã«å€æããæ®ããèŠæ±æ¬äœãžã®åŒæ°ãšããŠå€æãããããã®ãã©ã¡ãŒã¿ãŒã§æšæºã®HttpClient
ãåŒã³åºãã ãã§ãã ãã®çµæãåãSerializationConstant
ãã¹ãŠã®åé¡ã¯ããã®ãã³ãã©ãŒã§1åããèšè¿°ãããªãã£ããšããäºå®ã«ãã£ãŠè§£æ±ºããã1忣ããå®è£
ã§ããåžžã«æ£ããçµæãåŸãããŸããã ããã»ã©é·ããªãå«ç
ææžãšã¹ã¿ãã¯ãªãŒããŒãããŒã®åŸãMVPã¯æºåãã§ããŠããŸããã
ããã§ããµãŒãã¹ã䜿çšããã«ã¯ã次ã®ããã«ããŸãã
- ã€ã³ã¿ãŒãã§ãŒã¹ãäœæãã
public interface ISampleClient : ISampleService, IDisposable { }
- ç§ãã¡ã¯å°ããªã©ãããŒãæžããŠããŸãïŒãããªã䜿çšã®äŸ¿å®äžïŒã
public static ISampleClient New(Uri baseUri, TimeSpan? timeout = null) { return BaseUriClient<ISampleClient>.New(baseUri, Constant.ServiceSampleUri, timeout); }
ç§ãã¡ã¯äœ¿çšããŸãïŒ
[Fact] public async Task TestHelloAsync() { var manager = new ServiceManager(); manager.RunAll(BaseAddress); using (var client = SampleClient.New(BaseAddress)) { var hello = await client.GetHello(); Assert.Equal(hello, "Hello"); } manager.CloseAll(); }
å
責äºé
ãã¡ããããã®ãã¹ãã§ã¯ãå®éã®èŠæ±ãè¡ãå®éã®WCFãµãŒãã¹ãçºçãããããå³å¯ã«èšãã°ããã¯åäœãã¹ãã§ã¯ãããŸããã ããããç§ãã¡ã¯çãç§ãã¡ã®éã¡ããåŠã³ãŸããä»ãç§ã¯äžæ¯ãéã蟌ããŠããã¹ãŠãç°ãªãããæ¹ã§ããŸããããã®æãç§ã¯ãŸã æ¹æ³ãç¥ããŸããã§ããã
ãã¹ãŠãéåžžã«åçŽã§ãçè§£ã§ããããã«ãç¹å¥ãªã¯ã©ã¹ã®ç¶æ¿ã屿§ã®ä»å ãªã©ã®ç¹å¥ãªéæ³ã¯å¿
èŠãããŸããã 倿°ãšã¡ãœããåã¯èªåçã«è¡šç€ºãããŸãã äžè¬çã«ãçŸããã ããã«ãæ¯åãµãŒãã¹ã®ååã§å®æ°æååãæå®ããã®ãé¢åã§ã¯ãªãå Žåãé
ç®2ââã¯çç¥ã§ããŸãã
ã©ã®ããã«æ©èœããŸããïŒ å®éãååãªé»éè¡ã§ã ãããã·ã¡ãœãããçæããäž»ãªéšåã¯æ¬¡ã®ãšããã§ãã
private static void ImplementMethod(TypeBuilder tb, MethodInfo interfaceMethod) { var wcfOperationDescriptor = ReflectionHelper.GetUriTemplate(interfaceMethod); var parameters = GetLamdaParameters(interfaceMethod); var newDict = Expression.New(typeof(Dictionary<string, object>)); var uriDict = Expression.Variable(newDict.Type);
å°ããªã¯ã€ãºïŒ2è¡c ReflectionHelper.GetPropertyInterfaceImplementation<IWcfRequest>()
泚æããŠãã ããã ãªããããå¿
èŠã ãšæããŸããïŒ ãªãã¬ã¯ã·ã§ã³ã®ãªãã¬ã¯ã·ã§ã³ã¯ãåã«æžãã®ã§ã¯ãªããèªåãæããã®ãçæããã³ãŒããæžãæ¹ãé¢çœãã§ããïŒ
ããã§ã®äž»ãªãã€ã³ãã¯ãåŒã䜿çšããŠã¡ãœããã®æ¬äœãçæãããã¹ãŠã®åŒæ°ãæ¬äœãŸãã¯queryStringã®ããããã«é
眮ããCompileToInstanceMethodæ¡åŒµæ©èœã䜿çšããŠããªã²ãŒãã«ã§ã¯ãªããããã«ã¯ã©ã¹ã¡ãœããã«ã³ã³ãã€ã«ããããšã§ãã ããã¯ããã»ã©é£ããããšã§ã¯ãããŸããããäœæ¥ããŒãžã§ã³ãåŸããããŸã§æ°ååã®å埩ãè¡ãããæ£ããããŒãžã§ã³ãçµæ¶åãããŸããã
internal static class XLambdaExpression { public static MethodInfo CompileToInstanceMethod(this LambdaExpression expression, TypeBuilder tb, string methodName) { var paramTypes = expression.Parameters.Select(x => x.Type).ToArray(); var proxyParamTypes = new Type[paramTypes.Length - 1]; Array.Copy(paramTypes, 1, proxyParamTypes, 0, proxyParamTypes.Length); var proxy = tb.DefineMethod(methodName, MethodAttributes.Public | MethodAttributes.Virtual, expression.ReturnType, proxyParamTypes); var method = tb.DefineMethod($"<{proxy.Name}>__Implementation", MethodAttributes.Private | MethodAttributes.Static, proxy.ReturnType, paramTypes); expression.CompileToMethod(method); proxy.GetILGenerator().EmitCallWithParams(method, paramTypes.Length); return proxy; } }
æãæ²ããããšã¯ããããæ¯èŒçèªã¿ããããªãã·ã§ã³ã§ãããCompileToMethodã¢ãã¬ãããããããåé€ããããããCoreã«ç§»åããåŸã¯æŸæ£ããªããã°ãªããªãã£ãããšã§ãã ãã®çµæãå¿åããªã²ãŒããçæã§ããŸãããã¯ã©ã¹ã¡ãœããã¯çæã§ããŸããã ãããŠããããå¿
èŠãªãã®ã§ãã ãããã£ãŠãçã®ããŒãžã§ã³ã§ã¯ãããã¯ãã¹ãŠå€ããã®ã«çœ®ãæããããŸã ããã ILGeneratorã ãã®å Žåã®å
žåçãªããªãã¯ã¯ãCïŒã³ãŒããèšè¿°ããildasmã§è§£æãããããã©ã®ããã«æ©èœãããã確èªããããšã§ããããã§ãäžè¬çãªã±ãŒã¹ãã«ããŒããããã«åŸ®èª¿æŽããå¿
èŠããããŸãã ILãèªåã§èšè¿°ããããšãããšã99ïŒ
ã®ã±ãŒã¹ã§ã å
±éèšèªã©ã³ã¿ã€ã ãç¡å¹ãªããã°ã©ã ãæ€åºããããšãã§ããŸã:)ãšã©ãŒã ãããããã®å Žåãæçµçãªã³ãŒãã¯ãæ¯èŒçèªã¿ãããåŒãããçè§£ããã®ãã¯ããã«å°é£ã§ãã
ãã®Cookieãæš¹ç®ããåãåºãåé¡ã«ã€ããŠã¯ã ããã§èª¬æããŸã ïŒãªã¹ãã®æåã®é
ç®ã«èå³ããããŸãïŒããèŠæ±ã¯ããªãæ»ãã§ããããã«èŠããŸãã ãããããã¹ãŠãããã»ã©æªãããã§ã¯ãããŸãããããã«è¯ã解決çãèŠã€ãã£ãããã§ãïŒ
第3å¹ïŒã³ã³ãã€ã©ãŒã®ã«ããŒäž

ãã®å
šäœã100åæžãçŽãããããã°ããåŸãã³ã³ãã€ã«ã®æ®µéã§ããããã¹ãŠã§ããªãã®ã¯ãªãããšæããŸããã ã¯ããçæãããã¿ã€ãã®ãªãŒããŒãããããã£ãã·ã¥ããããšã§ãã¯ã©ã€ã¢ã³ãã®äœ¿çšã¯ãããããã§ããActivator.CreateInstanceãåŒã³åºãã ãã§æžã¿ãŸããããã¯ãç¹ã«ã·ã³ã°ã«ãã³ãšããŠäœ¿çšã§ãããããHTTPãªã¯ãšã¹ãå
šäœãäœæããã³ã³ããã¹ãã§ã¯äºçްãªããšã§ãã ãµãŒãã¹URL以å€ã®ç¶æ
ã¯ãããŸããã ããã§ããããã«ã¯é©åãªå¶éããããŸãã
- çæãããã³ãŒããèŠãŠææ¡ããããšã¯ã§ããŸããã ååãšããŠãããã¯å¿
èŠãããŸããã ããã¯åå§çã§ãããæçµçãªäœæ¥ã³ãŒããäœæãããŸã§ããªãæå³ãããšããã«æ©èœããªãã®ãã«ã€ããŠå€ããæšæž¬ããå¿
èŠããããŸããã çµè«ïŒãŸã 楜ãã¿ãªããåçãã«ãããããã°ãã
- ã¯ã©ã€ã¢ã³ãã¯åžžã«ã¯ã©ã€ã¢ã³ããšåãã€ã³ã¿ãŒãã§ãŒã¹ãæã£ãŠããå¿
èŠããããŸãã ãã€äžå¿«ã§ããïŒ ããšãã°ããµãŒããŒã«åæã¢ããªã±ãŒã·ã§ã³ãããããã¯ã©ã€ã¢ã³ãã§ã¯HTTPèŠæ±ã§ãããããéåæã§ããå¿
èŠããããŸãã ãããã£ãŠãã¹ããªãŒã ããããã¯ããŠå¿çãåŸ
ã€ãããã¹ãŠã®ãµãŒããŒã¡ãœãããéåæã«ããå¿
èŠããããŸããå¿
èŠã®ãªãå Žåã§ãããµãŒãã¹ã«åŒ·å¶çã«Task.FromResultãé
眮ãããŸãã
- å®è¡æã«ãªãã¬ã¯ã·ã§ã³ãåãé€ãããšã¯åžžã«çŽ æŽãããããšã§ã
ã¡ããã©ãã®æãRoslynã«ã€ããŠè峿·±ãããšãããããèããŸãããRoslyn-Microsoftã®æ°ããã¢ãžã¥ã©ãŒã³ã³ãã€ã©ã§ãããã»ã¹ãããæ·±ãæãäžããããšãã§ããŸãã åœåãLLVMã®ããã«ãç®çã®å€æçšã®ããã«ãŠã§ã¢ãç°¡åã«äœæã§ããããšãæ¬åœã«æåŸ
ããŠããŸããããããã¥ã¡ã³ããèªãã åŸãRoslynã§äžèŠãªãžã§ã¹ãã£ãŒãªãã§æ¬æ Œçãªã³ãŒãçæãè¡ãããšã¯ã§ããªããšããå°è±¡ãåããŸããïŒããã¯LINQãloopã«çœ®ãæãããããžã§ã¯ãã§è¡ãããŸãããæãããªçç±ã§ããŸã䟿å©ã§ã¯ãããŸããïŒããŸãã¯ãããã§ã³ã³ããå¿ããŠããŸã£ãã®ã§ãæ¿å
¥ããŠãã ããããšããã¹ã¿ã€ã«ã®ã¢ãã©ã€ã¶ãŒã§ãã ãããŠãç§ã¯ãã®ãããã¯ã®èšèªãªããžããªãgithubã«ããè峿·±ãæ©èœãªã¯ãšã¹ãã«ééããŸããïŒ tyts ïŒãããã®åŸã2ã€ã®åé¡ãããã«çŸããŸããïŒæåã«ããã®æ©èœã®éåžžã«é·ããªãªãŒã¹åã«ããããŠæ¬¡ã«ã圌ãã¯ãããäœæ¥ãã©ãŒã ã¯ãç§ã«ã¯äœã®å©ãã«ããªããŸããã ãã¹ãŠãããã»ã©æªãã¯ãããŸããã§ããããã³ã¡ã³ãã§ç§ãå¿
èŠãªããšãããŠããããã«èŠããè峿·±ããããžã§ã¯ããžã®ãªã³ã¯ãç§ã«äžããŠãããããã§ãã
æ°æ¥æãé²ããŠåºæ¬çãªãããžã§ã¯ãããã¹ã¿ãŒããåŸãç§ã¯ãããããŸãããããšã«æ°ä»ããŸããïŒ ãããŠãããã¯æ¬æ¥ã©ããã«æ©èœããŸãã éæ³ã®ãããªãã®ã§ãã éåžžã®ã³ã³ãã€ã©ãŒã®äžã«ç¬èªã®ã³ã³ãã€ã©ãŒãäœæããã®ãšã¯ç°ãªããããã§ã¯ããœãªã¥ãŒã·ã§ã³ã«ç°¡åã«ãã©ã°ã€ã³ã§ããéåžžã®nugetããã±ãŒãžãäœæããŸãããã«ãäžã«ãæ±ãäœæ¥ãè¡ããŸãããã®å ŽåããµãŒãã¹ã®ã¯ã©ã€ã¢ã³ãã³ãŒããçæããŸãã ã¹ã¿ãžãªãšå®å
šã«çµ±åãããŠãããããäœãããå¿
èŠã¯ãããŸãã-ãã³ã»ã³ã¹ã 確ãã«ããœãªã¥ãŒã·ã§ã³ã®æåã®ã€ã³ã¹ããŒã«åŸã®ããã¯ã©ã€ãã¯æ©èœããŸãããããœãªã¥ãŒã·ã§ã³ã®åæ§ç¯ãšåçºèŠåŸã¯ãããã¯ã©ã€ããšIntelliSenseã®äž¡æ¹ãæ©èœããŸãïŒ ç¢ºãã«ããã¹ãŠãæ©èœããããã§ã¯ãããŸãããããšãã°ã<inheritdoc />ã䜿çšããŠã€ã³ã¿ãŒãã§ã€ã¹ããæ¡åŒµããã¥ã¡ã³ãã衚瀺ããæ¹æ³ã¯ãŸã ããããŸãããäœããã®çç±ã§ãã¹ã¿ãžãªã¯ãããå®è¡ããããªãã ãã§ãã ããŠã倧äžå€«ãäž»ãªããšã¯å®äºã§ã-ã¯ã©ã¹ãçæãããããããåäœããçæã®çµæã¯åžžã«ãã²ãããä»ããŠã¯ã³ã¯ãªãã¯ã§èšå®ãããã¹ãã€ããä¿®æ£ãããŸãã æã¿ã©ããã®ãã¹ãŠã
ãŠãŒã¶ãŒã®å Žåãäœ¿çšæ¹æ³ã¯æ¬¡ã®ããã«ãªããŸãã

ã€ã³ã¿ãŒãã§ãŒã¹ãèšè¿°ããããã€ãã®å±æ§ããã³ã°ã¢ããããã³ã³ãã€ã«ããã ãã§ãçæãããã¯ã©ã¹ã䜿çšã§ããŸãã PostSharpã¯å¿
èŠãããŸããïŒ ïŒåè«ïŒã
ããã§ã¯ãã©ã®ããã«æ©èœããŸããïŒ
第4å¹ïŒæ±ºå
åœåãç§ã¯æ·±ãè¡ãã€ããã¯ãããŸããã§ããããªããªã ãã§ã«ç§ã®èŠä»¶ãå®å
šã«æºãã宿ããã©ã€ãã©ãªããããŸããããã¢ãã©ã€ã¶ãäœæããŠããã±ãŒãžãäœæããã ãã§ããã ããããæäŸãããAPIã®äžé©åãªäœ¿çšããŸãã¯ã©ã€ãã©ãªèªäœã®ãšã©ãŒãŸãã¯æ¬ ç¹ã®ããã«ãçŸå®ã¯ããæ·±å»ã§ããšã©ãŒããã£ããããããšã倿ããŸããããé¿ããããªãå ±åŸ©ã¯äŸç¶ãšããŠç§ã远ãè¶ããŸããã æçµçã«ãã¹ãŠãäžã®åçã®ããã«èµ·åããããã«ãç§ã¯ãããææ¡ããå¯èŒžããªããã°ãªããŸããã§ããã
å®éãã»ãšãã©ãã¹ãŠã®ãœã«ãã¯æ°ãã.Net CoreããŒã«ãã§ãŒã³ã«ãããŸãã
<Project Sdk="Microsoft.NET.Sdk"> <PropertyGroup> <PackageType>DotnetCliTool</PackageType> <OutputType>Exe</OutputType> <TargetFramework>netcoreapp1.0</TargetFramework> <AssemblyName>dotnet-codegen</AssemblyName> </PropertyGroup> </Project>
æ¬è³ªçã«ãããã¯ãããžã§ã¯ããæ§ç¯ãããšãã«ããã«ãŠã§ã¢ã決å®ããæ¹æ³ã§ãã ãã®åŸãã³ã³ãã€ã©ã¯dotnet-codegenãäœã§ããããçè§£ããåŒã³åºãããšãã§ããŸãã ãããžã§ã¯ãããã«ããããšã次ã®ããã«è¡šç€ºãããŸãã

ãã«ããã¯ãªãã¯ãããšãïŒãŸãã¯åã«ãã¡ã€ã«ãä¿åãããšãã§ãïŒïŒïŒ
CodeGeneration.Roslyn.Tasks
ã¢ã»ã³ããªããGenerateCodeFromAttributes
ããããŸããããã¯ã Microsoft.Build.Utilities.ToolTask
ãç¶æ¿ãããããžã§ã¯ãã®ã¢ã»ã³ããªäžã«ããããã¹ãŠã®éå§ã決å®ããŸãã å®éãåºåãŠã£ã³ããŠã§ãã®ã¿ã¹ã¯ã®äœæ¥ãå°ãé«ããªã£ãŠããŸãã- ããã¹ããã¡ã€ã«
CodeGeneration.Roslyn.InputAssemblies.txt
ãŸãã CodeGeneration.Roslyn.InputAssemblies.txt
ãåéããã¢ã»ã³ããªãžã®ãã«ãã¹ãæžã蟌ãŸããŸãã CodeGeneration.Roslyn.Tool
ãCodeGeneration.Roslyn.Tool
ãåæçšã®ãã¡ã€ã«ã®ãªã¹ããå
¥åã¢ã»ã³ããªãªã©ãååŸããŸãã äžè¬çã«ãäœæ¥ã«å¿
èŠãªãã¹ãŠã®ãã®ã- ããã§ã¯ããã¹ãŠãç°¡åã§ãããããžã§ã¯ãå
ã®
ICodeGenerator
ã€ã³ã¿ãŒãã§ã€ã¹ã®ãã¹ãŠã®åå«ãèŠã€ããã³ãŒããçæããå¯äžã®GenerateAsync
ã¡ãœãããåŒã³åºããŸãã - ã³ã³ãã€ã©ã¯ãobjãã£ã¬ã¯ããªããçæãããæ°ãããã¡ã€ã«ãèªåçã«ååŸããçµæã®ã¢ã»ã³ããªã«è¿œå ããŸã
ãã®çµæããã®ã©ã€ãã©ãªã®çŸåšã®ããŒãžã§ã³ã§ã¯ãäžéšã®ã¯ã©ã¹ã«å±æ§ãæããŠãæåéã100è¡ã®ã³ãŒããèšè¿°ã§ããŸããããã«åºã¥ããŠãå¿
èŠãªãã¹ãŠãçæãããŸãã å¥ã®ã¢ã»ã³ããªã®ã¯ã©ã¹ãçæã§ããªããšããå¶éããããŸããã€ãŸããçæãããã¯ã©ã¹ã¯åžžã«ã³ã³ãã€ã«ããåãã¢ã»ã³ããªã«è¿œå ãããŸãããååãšããŠãããšå
±åã§ããŸãã
远å ã®è¡çºïŒèŠçŽ
ãã®ã©ã€ãã©ãªãæžãããšãã誰ãã«åœ¹ç«ã€ãšæåŸ
ããŠããŸããããããã§ãããã£ããããŸããã Swaggerã¯åãã¿ã¹ã¯ãå®è¡ããŸãããåæã«ã¯ãã¹ãã©ãããã©ãŒã ã§ããã䟿å©ãªã€ã³ã¿ãŒãã§ãŒã¹ãåããŠããŸãã ããããããã«ãããããããç§ã®å Žåã¯ãåã«ã¿ã€ãã倿Žãããã¡ã€ã«ãä¿åããŠããã«ã³ã³ãã€ã«ãšã©ãŒãååŸã§ããŸãã ãã¹ãŠãéå§ããããã®ïŒ

æåŸã«å€§äºãªããšãèšãå¿ããŸããããç§ã¯ãã®ãã¹ãŠãå®è£
ããããšã§å€ãã®åã³ãåŸãŸããããŸããç§ã«ã¯æããããã«ãèšèªãšã³ã³ãã€ã©ã«ã€ããŠã®ååãªç¥èãåŸãŸããã ãããã£ãŠãç§ã¯èšäºãæžãããšã«ããŸããïŒå€åäžçã¯æ°ããã¹ã¯ã¬ãŒãå¿
èŠãšããªããããããŸããããã³ãŒãçæãå¿
èŠãªå ŽåãT4ã¯è»œspãããããªãã«åãããåå°ã¯ç§ãã¡ã®ãªãã·ã§ã³ã§ã¯ãããŸããããããŠããã«çŽ æŽãããä»äºãããçŽ æŽãããããŒã«ããããŸããçŽ æŽãããçŸåšã®ãã€ãã©ã€ã³ã«çµ±åããããã®çµæãnougatããã±ãŒãžã®ããã«åºãããŸãã ã¯ããã¹ã¿ãžãªããã®ããã¯ã©ã€ããå«ãŸããŠããŸãïŒ ïŒãã ãããœãªã¥ãŒã·ã§ã³ã®ç¬¬1äžä»£ãšåçºèŠåŸã®ã¿ïŒã
ç§ã¯ããã®ããã»ã¹ãã³ã¢ãã¬ãŒã ã¯ãŒã¯ã§ã¯ãªã倧人ã®ãã¬ãŒã ã¯ãŒã¯ã§è©Šããããšã¯ãªãã®ã§ãããã«èšãå¿
èŠããããŸãã ãã ãããã®ããã±ãŒãžã®ã¿ãŒã²ããã«ã¯ã portable-net45+win8+wpa81
ã portable-net4+win8+wpa81
ãããã«ã¯net20
ãå«ãŸããããšãèæ
®ãããšãç¹å¥ãªåé¡ã¯ãããŸããã ããã«äœããäœåãªäŸåé¢ä¿ã NIHãæ°ã«å
¥ããªãå Žåã§ããç¬èªã®ãããã³ãŒã·ã£ã®ããå®è£
ããã€ã§ãäœæã§ããŸããã³ãŒãã«ã¯å€ãã®ã¡ãªããããããŸãã å¥ã®èœãšã穎ã¯ãããã°ã§ããç§ã¯ãã®ãã¹ãŠããããã°ããæ¹æ³ãçè§£ããŠããŸããã§ãããã³ãŒãã¯ç²ç®çã«æžãããŸããã ãããããã€ãã£ãCodeGeneration.Roslyn
ã©ã€ãã©ãªã®CodeGeneration.Roslyn
è
ã¯ããããžã§ã¯ãã®æ§é ãèŠãã ãã§ééããªãå¿
èŠãªç¥èãæã£ãŠããŸãããæçµçã«ã¯ãããã䜿çšããŸããã§ããã
ãããŠä»ãç§ã¯æç¢ºãªè¯å¿ããã£ãŠèšãããšãã§ããŸãïŒç§ã¯ç§ãå¥ã®swæ©ãæžããããšãå
šãåŸæããŠããŸããã
åç
§ïŒ
ç§ã®ãããžã§ã¯ãã¯ãã¹ãŠMITã©ã€ã»ã³ã¹ãfork-study-breakã®äžã«ãããŸãããç§ã¯èŠæ
ã¯ãããŸãã:)
åœåããããã¯ãã¹ãŠå®å
šã«æ©èœãããããžã§ã¯ããšããŠèšç»ãããŠããŸããããå®éã®èŠä»¶ã®çµæãšããŠçŸãããããææªã®å Žåããã€ããŒãªããã«ã«ã®åŸããã¹ãŠãå®çšŒåã§äœ¿çšã§ããŸãã
ãã¡ããã質åã«å¯Ÿããçãã¯æ¬¡ã®ãšããã§ãã
- MethodImplOptions.NoInliningã¯ãåŒã³åºãå¿
èŠãããã¡ãœããã®ååãæ±ºå®ããããã«äœ¿çšãããŸãã ãªããªã ã»ãšãã©ã®ã¡ãœããã¯éåžžã«åçŽã§ãããããå€ãã¯æåéãåäžè¡ã§ãããã³ã³ãã€ã©ãŒã¯ããããã€ã³ã©ã€ã³åããããšã奜ã¿ãŸãã ãåç¥ã®ããã«ãã³ã³ãã€ã©ãŒã¯32ãã€ãæªæºã®æ¬äœã§ã¡ãœãããã€ã³ã©ã€ã³åããŸãïŒãŸã å€ãã®æ¡ä»¶ããããŸãããããã«çŠç¹ãåœãŠãããšã¯ãããŸããããããã¯ãã¹ãŠããã§æºããããŸããïŒããããã£ãŠã倿°ã®åŒæ°ãæã€ã¡ãœãããæ£åžžã«åŒã³åºããããšããé¢çœããã°ãèŠãããšãã§ããŸã-å®è¡æã«ãšã©ãŒãã¹ããŒãã é©åãªã¡ãœãããèŠã€ããããã³ãŒã«ã¹ã¿ãã¯ã®æäžéšã«å°éããŸãã
MethodBase method = null; for (var i = 0; i < MAX_STACKFRAME_NESTING; i++) { var tempMethod = new StackFrame(i).GetMethod(); if (typeof(TService).IsAssignableFrom(tempMethod.DeclaringType)) { method = tempMethod; break; } }
- å®éã®ãšãããreflexã¡ãœãããäœæãããšããçŸåšã®
RemoteClient.Core
ã¢ã»ã³ããªã§ã¯ãªããåçã«äœæãããã¯ã©ã¹ã«ã¯ã©ã¹ã远å ããŠãããšã¯æ¬åœã«æã£ãŠããŸããã§ããã ããã¯éåžžã«éèŠã§ãã ãã®çµæããã¹ãŠã®æ©èœããã¹ãããããããã¹ãŠãæ©èœãããšããèªä¿¡ãç²åŸããåŸã WcfRequest
ã¯ã©ã¹ããããªãã¯ã§ããããšãWcfRequest
ã ãé害ãã¯ããå®è£
ã¯ãã©ã€ããŒãã§ãããã€ã³ã¿ãŒãã§ã€ã¹ã®ã¿ã衚瀺ãããã¹ãã ããšèããŸããã ãããŠãå
éšå±æ§ãèšå®ããŸãã ãããŠãããã¯ãã¹ãŠå£ããŸããã çç±ã¯ç°¡åã§ãã芪ã¢ã»ã³ããªA.dll
å
éšã¯ã©ã¹ãã€ã³ã¹ã¿ã³ã¹åããããšããã¢ã»ã³ããªA.Dynamicalygenerated.dll
ãçæããã¢ã¯ã»ã¹ãšã©ãŒã§èªç¶ã«ã¯ã©ãã·ã¥ããŸãã ããŠãããã¯ãã¢ã»ã³ããªéã«äžæå¿«ãªåŸªç°äŸåãåŸããšããäºå®ãæ°ããŠããŸããã ãã®çµæããã¹ãŠã®ããããã£ã«ã»ãã¿ãŒãåçŽã«è¿œå ããããããŒã¯ã©ã¹ãã®åççæã¯ãããªãåçŽãªãœãªã¥ãŒã·ã§ã³ã§ããããšã倿ããåæã«ãçæãããã¢ã»ã³ããªã«ã€ããŠA.dll
çŽæ¥äŸåããããŒã«ãæããªããšããæå³ã§äŸ¿å©ã«ãªããŸãããè£åŽã