MS_TransparentProxyForAOP - NetDevInfraWGinOSSConsortium/NetDevInfraWiki GitHub Wiki
- æ»ãïŒAOPïŒ
.NET Framework ã§ AOP ãå®çŸããããã®ææ³ã®ïŒã€ã§ãã
ãééãããã·ïŒRealProxy ã¯ã©ã¹ïŒãã®æŠèŠãäœ¿çšæ¹æ³ã
ãããŠããµã³ãã« ã³ãŒãã«ã€ããŠèª¬æããã
ã³ã³ã§ã¯ã.NET Framework ã§ AOP ãå®çŸããããã®
ææ³ã®ïŒã€ã§ããééãããã·ã«ãã©ãŒã«ã¹ããŠããã説æããã
ç§»è¡ã¡ã¢ïŒ
RealProxy㯠.NET Framework å°çšïŒ: æ¬ããŒãžãèªãåã«ã
éèŠãªåæã瀺ããŠããããRealProxy / MarshalByRefObject ã®çŸæ³ã ã»System.Runtime.Remoting åå空éã«å±ãã ã»ã.NET Remoting 㯠.NET Core 以éã«ç§»æ€ãããªãã£ããâ ã»ãããã£ãŠ RealProxy ã¯ã.NETïŒCore ç³»ïŒã§ã¯äœ¿ããªãã â RealProxy ã¯ã©ã¹èªäœãååšããªã â MarshalByRefObject ã¯åãšããŠã¯ååšãããã ãªã¢ãŒãåŠçã®æ©èœã¯äŒŽããªãæ¬ããŒãžã®äŸ¡å€ã¯ãAOP ã®ä»çµã¿ãã®ãã®ã®çè§£ã«ããã
ãä»ãéçšããéšåã ã»ãåŒã³åºããæšªåãããŠãååŸã«åŠçãæãããšãããåçãâ ã»ã¡ãœãã ã·ã°ããã£ãå®è¡æã«åãåãã転éãããšããçºæ³ ã»ãã®ä»£åïŒæ§èœããããã°ã®é£ãããåã®å¶çŽïŒ ã眮ãæãã£ãéšåã ã»å®è£ ææ®µïŒRealProxy â åŸè¿°ã®ä»£æ¿ïŒçŸåšã®ä»£æ¿ã¯æ«å°Ÿã®è£è¶³ã«ãŸãšããã
ééãããã·ãšã¯ãçš®ã
ã®ãªã¢ãŒãåŠç åºç€æè¡ã䜿çšããŠ
å¢çãè¶ããªããžã§ã¯ãã転éããããã®ãããã·ã§ããã
- ã³ã³ã§ã¯ãAOP ãå®çŸããããã®ææ³ã®ïŒã€ãšããŠééãããã·ã掻çšããã
- ãŸããRealProxy ã¯ã©ã¹ã¯ééãããã·ãéçºããããã®éçºåºç€ã§ããã
ææïŒ
-
転éããããªããžã§ã¯ãã¯ãMarshalByRefObject ã¯ã©ã¹ãç¶æ¿ããå¿ èŠãããã
-
Microsoft Learn > .NET Framework ã¯ã©ã¹ ã©ã€ãã©ãª > MarshalByRefObject ã¯ã©ã¹
https://learn.microsoft.com/ja-jp/dotnet/api/system.marshalbyrefobjectMarshalByRefObject ã®ãMarshalãã¯ãäžè¬çã«ã¯ãéé æè»å Žã
ïŒåå²åšããã³ããªã©ãçµãŠç®çã®ä»åç·ã«éãèšåãã€ãŒããšãåŒã°ããïŒãæå³ãããã
IT çšèªãšããŠã¯ãCOM ãªã©ã§å®è£ ãããŠãããããŒã·ã£ãªã³ã°ããæãã
ã¢ããªã±ãŒã·ã§ã³ ãã¡ã€ã³ãããã»ã¹ãéçºæè¡ãªã©ã®åå¢çãè¶ããŠã
ãªããžã§ã¯ãã転éããæè¡ã®ç·ç§°ã§ããã
éçºæè¡ã®å¢çãè¶ããããã®æè¡ãšããŠã¯ãã¢ã³ãããŒãž DLL ããŒã·ã£ãªã³ã°ãªã©ãããã
.NET ãªããžã§ã¯ãåŒæ°ã Win32 DLL ã§äœ¿çšå¯èœãªããŒã¿åã®åŒæ°ã«å€æïŒãŸãã¯ãã®éãïŒããã
ãªããã³ã³ã§ã¯ãMarshalByRefObjectïŒããŒã·ã£ãªã³ã°ïŒæè¡ã®è©³çްã«ã€ããŠã¯è§Šããªãã
-
-
RealProxy ã¯ã©ã¹ã¯ abstract åºæ¬ã¯ã©ã¹ã§ããã
ééãããã·ãéçºããéã¯ããã® RealProxy ã¯ã©ã¹ãç¶æ¿ããå¿ èŠãããã- Microsoft Learn > .NET Framework ã¯ã©ã¹ ã©ã€ãã©ãª > RealProxy ã¯ã©ã¹
https://learn.microsoft.com/ja-jp/dotnet/api/system.runtime.remoting.proxies.realproxy
- Microsoft Learn > .NET Framework ã¯ã©ã¹ ã©ã€ãã©ãª > RealProxy ã¯ã©ã¹
è£è¶³ïŒ
MarshalByRefObjectãå¿ èŠãªçç±ïŒ: ãç¶æ¿ããå¿ èŠãããã
ãšããå¶çŽã¯ããã®æ¹åŒã®æå€§ã®åŒ±ç¹ã§ãããã®ã§ã
çç±ãšåž°çµãæèšããŠããããçç±ã CLR ã¯ãMarshalByRefObject ãç¶æ¿ããåãã«å¯ŸããŠã®ã¿ã ãåç §æž¡ãïŒby referenceïŒïŒ ãããã·çµç±ã®åŒã³åºãããèš±ã â CLR ãåŒã³åºããæšªåãã§ããã®ã¯ããã®åã«éããã â ãéåžžã®ãªããžã§ã¯ãã ã¢ããªã±ãŒã·ã§ã³ ãã¡ã€ã³ãè·šããšã倿ž¡ããïŒã·ãªã¢ã©ã€ãºïŒ ãŸãã¯è·šããªããåž°çµïŒãã®å¶çŽãå®çšäžã®é害ã«ãªããâ ã»å¯Ÿè±¡ã¯ã©ã¹ã«ãMarshalByRefObject ãç¶æ¿ããããå¿ èŠããã â æ¢åã¯ã©ã¹ã®ç¶æ¿é¢ä¿ãå€ããããªãå Žåãé©çšã§ããªã â C# ã¯ãåäžç¶æ¿ããªã®ã§ãä»ã®åºåºã¯ã©ã¹ãšäž¡ç«ããªã â äŸïŒ Entity ã¯ã©ã¹ããã¬ãŒã ã¯ãŒã¯ã®åºåºã¯ã©ã¹ãç¶æ¿æžã¿ ã»sealed ã¯ã©ã¹ãstruct ã«ã¯é©çšã§ããªã ã»static ã¡ãœããã¯æšªåãã§ããªãããããåŸç¶ãå¥ã®æ¹åŒã«ãªã£ããçç±ã§ãããã
DispatchProxyïŒåŸè¿°ïŒã¯ã€ã³ã¿ãŒãã§ã€ã¹ãå®è£ ããæ¹åŒã§ããã
ç¶æ¿ã®å¶çŽãåé¿ããŠããã
以äžãééãããã·ã®åºæ¬çãªåäœã説æããã
-
ã¯ã©ã€ã¢ã³ãã¯ã䜿çšããããªããžã§ã¯ãïŒä»¥éããªããžã§ã¯ã A ãšç§°ãïŒã®æ å ±ã
ééãããã·ã«éç¥ãã -
ééãããã·ã¯ããªã¢ãŒãåŠç åºç€æè¡ã䜿çšããŠãªããžã§ã¯ã A ãçæããã
- ãªããžã§ã¯ããçæããæ¹æ³ãšããŠãäžèšã®æ¹æ³ãèããããã
- ã³ã³ã¹ãã©ã¯ã¿ããããªããžã§ã¯ãã»ã€ã³ã¹ã¿ã³ã¹ãçŽæ¥åãåãæ¹æ³
- ã³ã³ã¹ãã©ã¯ã¿ãããã¯ã©ã¹æ
å ±ãåãåãã
ããã䜿çšããŠãªããžã§ã¯ãã»ã€ã³ã¹ã¿ã³ã¹ãçæããæ¹æ³ - ã³ã³ã¹ãã©ã¯ã¿ããããªãã©ã«ãåãåããå®çŸ©æ
å ±ãã察å¿ããã¯ã©ã¹æ
å ±ãååŸã
ããã䜿çšããŠãªããžã§ã¯ãã»ã€ã³ã¹ã¿ã³ã¹ãçæããæ¹æ³
- ãªããžã§ã¯ããçæããæ¹æ³ãšããŠãäžèšã®æ¹æ³ãèããããã
-
ã¯ã©ã€ã¢ã³ãã¯ãªããžã§ã¯ã A ã®åç §ã®å€ããã«ééãããã·ã®åç §ãåŸãã
ãã®ééãããã·ã®åç §ã¯ããªããžã§ã¯ã A ã®åã«èšå®ããããšãã§ããããã
ã¯ã©ã€ã¢ã³ãã¯ããããããªããžã§ã¯ã A ãçŽæ¥æäœã§ãããã®ããã«é¯èŠããã

-
ééãããã·ã®åç §ã¯ããªããžã§ã¯ã A ã®åã«èšå®ãããŠããã®ã§ã
ãã®åã䜿çšããŠãªããžã§ã¯ã A ã«å¯ŸããåŒã³åºããå¯èœã§ããã -
ãã®ãªããžã§ã¯ã A ã®ã¯ã©ã¹åã䜿çšãããªããžã§ã¯ã A ãžã®åŒã³åºãã¯ïŒå®éã¯ïŒã
ééãããã·ã䜿çšããŠåŒã³åºããŠããã®ã§ãå§ãã«ééãããã·ã®
Invoke ã¡ãœããã«ããåŒã³åºããããã¯ãããã- ééãããã·ã§ã¯ãç¶æ¿ãã RealProxy ã® Invoke ã¡ãœããã
ãªãŒããŒã©ã€ãããå¿ èŠãããã
- ééãããã·ã§ã¯ãç¶æ¿ãã RealProxy ã® Invoke ã¡ãœããã

-
ééãããã·ã¯ãInvoke ã¡ãœããå ã§ãªã¢ãŒãåŠç åºç€æè¡ã䜿çšãã
åŒã³åºããå®éã®ãªããžã§ã¯ãã«è»¢éããã-
ééãããã·ã®ãã€ã³ãã¯ãééãããã·ã® Invoke ã¡ãœããã«ã¯ã
åŒã³åºãã¡ãœããã®ã¡ãœãã ã·ã°ããã£ã®æ å ±ãåŒæ°ãšããŠäžããããŠããç¹ã§ããã- ã¡ãœãã ã·ã°ããã£ãšã¯ãäžè¬çã«ã
ãã¡ãœããåããããã©ã¡ã¿æ°ãšé åºããã©ã¡ã¿ã®åãããæ»ãå€ã®åããªã©ãæå³ããã
- ã¡ãœãã ã·ã°ããã£ãšã¯ãäžè¬çã«ã
-
-
ééãããã·ã® Invoke ã¡ãœãããã䜿çšããããªããžã§ã¯ãã«åŒã³åºãã転éããå Žåã
æçµçã«ã¬ã€ããã€ã³ã æè¡ã䜿çšããããšã«ãªãã- .NET ã§ã¯ãSystem.Reflection åå空éã®ã¯ã©ã¹ã©ã€ãã©ãªã䜿çšããŠ
ã¬ã€ããã€ã³ããå®çŸããã
- .NET ã§ã¯ãSystem.Reflection åå空éã®ã¯ã©ã¹ã©ã€ãã©ãªã䜿çšããŠ
-
ã¬ã€ããã€ã³ãã䜿çšããå Žåã¯ãã¡ãœãã ã·ã°ããã£ãåºå®ããæ¹åŒãäž»æµã§ãããã
-
èšèªã«ãã£ãŠãç°ãªãããC++ãC# ã®ãããªã匷ãéçåä»ãããšãã
èšèªçç¹æ§ãæã€èšèªã«æŒããŠã¯ã
å®è¡ã«ä»»æã®ãªããžã§ã¯ãã«å¯ŸããŠä»»æã®ã¡ãœããåŒã³åºãã詊ã¿ããšããåŠçã
èš±å¯ãããŠããªãããã- C++ ã§ã¯ããããä»®æ³é¢æ°åŒã³åºãã COM ã§å®çŸããã
- C# ã§ã¯ãSystem.Reflection åå空éã®ã¯ã©ã¹ã©ã€ãã©ãªã䜿çšããŠå®çŸããã
- ããã«å¯ŸããVB ã§ã¯ object åã«ä»»æã®ã¡ãœããåŒã³åºããèšè¿°ã§ãã
-
-
ééãããã·ã® Invoke ã¡ãœããã«ã¯ã
åŒã³åºãã¡ãœããã®ã¡ãœãã ã·ã°ããã£ã®æ å ±ãåŒæ°ãšããŠäžããããããã
ããã䜿çšããŠãã©ã®ãããªã¡ãœããåŒã³åºãã転éããããšãã§ããã

è£è¶³ïŒ
Invokeã®å®è£ ïŒ: 説æã¯æ£ç¢ºãªã®ã§ã
å®éã®ã³ãŒãã瀺ããŠå ·äœåããŠãããpublic class LoggingProxy : RealProxy { private readonly MarshalByRefObject _target; public LoggingProxy(object target) : base(target.GetType()) // â åæ å ±ãåºåºã«æž¡ã => _target = (MarshalByRefObject)target; public override IMessage Invoke(IMessage msg) { var call = (IMethodCallMessage)msg; // â ã·ã°ããã£ã®æ å ± â // ãåãã¢ã¹ãã¯ã Log.Info($"â {call.MethodName}({string.Join(",", call.InArgs)})"); var sw = Stopwatch.StartNew(); try { // ãæ¬äœãã¬ã€ããã€ã³ãã§å®éã®ãªããžã§ã¯ããžè»¢é var result = call.MethodBase.Invoke(_target, call.Args); // ãåŸãã¢ã¹ãã¯ã Log.Info($"â {call.MethodName} ({sw.ElapsedMilliseconds}ms)"); return new ReturnMessage(result, call.Args, call.ArgCount, call.LogicalCallContext, call); } catch (TargetInvocationException ex) { // ãäŸå€ãã¢ã¹ãã¯ã Log.Error(ex.InnerException, call.MethodName); return new ReturnMessage(ex.InnerException, call); // â å åŽãè¿ã â } } } // äœ¿ãæ¹ var proxy = (ITarget)new LoggingProxy(new Target()).GetTransparentProxy(); proxy.DoSomething(); // â Invoke ãåŒã°ããå®è£ äžã®èŠç¹:
â ãTargetInvocationException ãå¥ãããâ Reflection çµç±ã®åŒã³åºãã§äŸå€ãåºããšã TargetInvocationException ã«å ãŸãã â InnerException ãè¿ããªããšã åŒã³åºãåŽãæ¬æ¥ã®äŸå€åã§ catch ã§ããªã â¡ ãReturnMessage ã« call.Args ãæž¡ãã out / ref åŒæ°ãæ£ããè¿ãããã«å¿ èŠ â¢ ãLogicalCallContext ãåŒãç¶ãã åŒã³åºãã³ã³ããã¹ãïŒ[Apache log4net](MS_ApacheLog4net) ã® LogicalThreadContext çïŒã倱ãããªãããã«ããåæã®ãVB ã§ã¯ object åã«ä»»æã®ã¡ãœããåŒã³åºããèšè¿°ã§ããã
ãšããææã¯æ£ããïŒOption Strict Offã§ã®é å»¶ãã€ã³ãã£ã³ã°ïŒã
çŸåšã® C# ã«ã¯dynamicãããããããã®å·®ã¯ãªããªã£ã
ïŒDLRïŒã
ééãããã·ã®åãã«ã€ããŠã¯ãåé ã§èª¬æããéãã§ããã
-
ãããŸã§ã®èª¬æã§æããã§ããããééãããã·ã䜿çšãã AOP ã®å®çŸæ¹æ³ãšã¯ã
ééãããã·ã® Invoke ã¡ãœããã«ã¢ã¹ãã¯ããå®è£ ããã ãã®ç°¡åãªãã®ã§ããã- ããã§ã¯ãééãããã·ã®æ¬æ¥ã®
ããªã¢ãŒãåŠç åºç€æè¡ã䜿çšããŠå¢çãè¶ããªããžã§ã¯ãã転éããã
圹å²ã¯äžèŠã§ããããããã®éšåã®å®è£ ãäžèŠã§ããã
- ããã§ã¯ãééãããã·ã®æ¬æ¥ã®
-
ãŸããæ§ã ãªä»æãïŒå®çŸ©æ å ±ãªã©ïŒãçšããããšã§ã
以äžã®æ§ãªæ©èœã远å ããããšãå¯èœã§ããã-
以äžãããŠã£ãŒãã³ã°ãããã¢ã¹ãã¯ãã®ãã¿ãŒã³ãå¯å€ã«ããã
- ã³ã³ã¹ãã©ã¯ã¿ã«æå®ããããªãã©ã«
- ã¡ãœããã«æå®ãããã¢ãããŒã·ã§ã³ïŒã¯ã©ã¹ / ã¡ãœãã屿§ïŒ
-
ã¢ã¹ãã¯ãã®å®è£ äœçœ®ããééãããã·äžããä»ã®ã¢ãžã¥ãŒã«äžãžç§»åãã
åŒã³åºãåŠçãéžæããã- ã³ã³ã¹ãã©ã¯ã¿ã«æå®ããããªãã©ã«
- ã¡ãœããã«æå®ãããã¢ãããŒã·ã§ã³ïŒã¯ã©ã¹ / ã¡ãœãã屿§ïŒ
-
ããããã³ã³ã§ã¯ããããã®å¿çšçãªå©ç𿹿³ãŸã§ã¯èª¬æããªãã
è£è¶³ïŒãã®æ¹åŒã¯ãåçãŠã£ãŒãã³ã°ãã§ããïŒ: AOP ã®
åé¡ã§ãããšãæ¬ããŒãžã®ææ³ã¯å®è¡æãŠã£ãŒãã³ã°ã«åœããã
æ¹åŒ ãã€ç¹ã蟌ãã ä»£è¡šäŸ ã³ã³ãã€ã«æãŠã£ãŒãã³ã° ãã«ãæã« IL ãæžãæãã PostSharpãAspectInjector ããŒãæãŠã£ãŒãã³ã° ã¢ã»ã³ããªèªã¿èŸŒã¿æ Fody å®è¡æãŠã£ãŒãã³ã°ïŒåçãããã·ïŒ ãªããžã§ã¯ãçææã«ãããã·ã被ãã RealProxy â ãCastle DynamicProxyãDispatchProxy ãåçãããã·ã®å©ç¹ã ã»ãã«ã ããã»ã¹ãå€ããªã ã»å¯Ÿè±¡ãå®è¡æã«åãæ¿ããããïŒèšå®ã§ ON/OFFïŒâ ã»ãããã°æã«å ã®ã³ãŒãããã®ãŸãŸèŠãã ãåçãããã·ã®æ¬ ç¹ã ã»ãåŒã³åºãããšã«ãªãŒããŒãããããããïŒReflectionïŒ ã»ãããã·çµç±ã§ãªããšå¹ããªã â new ããçŽæ¥ã®ã€ã³ã¹ã¿ã³ã¹ã«ã¯å¹ããªã â â ãDI ã³ã³ãããšçµã¿åããããã®ãåæã«ãªã ã»sealed / static / private ã«ã¯å¹ããªãåæãæãããã¢ãããŒã·ã§ã³ïŒå±æ§ïŒã§ã¢ã¹ãã¯ããå¯å€ã«ããã
ãšããçºæ³ããçŸåšã®å®è£ ã§ãäžå¿çã§ããã[AttributeUsage(AttributeTargets.Method)] public class LogAttribute : Attribute { } // Invoke ã®äžã§å±æ§ãèŠãŠãä»ããŠããã¡ãœããã ããã°ãåºã if (call.MethodBase.GetCustomAttribute<LogAttribute>() is not null) { /* ... */ }ã屿§ã§æå®ããå©ç¹ã ã»ã©ãã«ã¢ã¹ãã¯ããå¹ããããã³ãŒãäžã§èŠãããâ â ããªãããã°ãåºã/ãã©ã³ã¶ã¯ã·ã§ã³ã匵ãããããé²ã ã»èšå®ãã¡ã€ã«ãã远跡ãããã ãAOP å šè¬ã®æ³šæãïŒ[AOP](MS_AOP) ã«ãèšèŒïŒ ã»ãèŠããªãå Žæã§åŠçãæãŸããïŒ è¿œè·¡ãå°é£ã«ãªããã ã»é©çšå¯Ÿè±¡ã¯ã暪æçé¢å¿äºãã«éã ãã°ããã©ã³ã¶ã¯ã·ã§ã³ãèªå¯ããã£ãã·ã¥ããªãã©ã€ãèšæž¬ ã»æ¥åããžãã¯ã AOP ã«å ¥ããªã
-
ééãããã·ã䜿çšãã AOP ã®åäœç¢ºèªçš
ãµã³ãã« ããã°ã©ã ãçšããŠãAOP ã®å®è£ æ¹æ³ã説æããã- ãµã³ãã« ããã°ã©ã 㯠Console ã¢ããªã±ãŒã·ã§ã³ã§äœæãããŠããã
- ãããžã§ã¯ãã®æ§æã¯æ¬¡ã®ããã«ãªã£ãŠããã
-
ãµã³ãã« ããã°ã©ã
RealProxy.zip -
ã¯ã©ã¹ïŒã¢ãžã¥ãŒã«ïŒäžèЧ
| é çª | ã¯ã©ã¹ïŒã¢ãžã¥ãŒã«ïŒ | 説æ |
|---|---|---|
| ïŒ | TG.cs | ã¿ãŒã²ãã ã¯ã©ã¹ïŒã³ã³ã§èšããªããžã§ã¯ã A |
| ïŒ | PR1.cs | ééãããã·ïŒïŒãªããžã§ã¯ã A ã®ã€ã³ã¹ã¿ã³ã¹ãæž¡ãããŒãžã§ã³ |
| ïŒ | PR2.cs | ééãããã·ïŒïŒãªããžã§ã¯ã A ã®ã¯ã©ã¹åæ å ±ãæž¡ãããŒãžã§ã³ |
| ïŒ | MyInt.cs | åç §åãåŒæ°ã«äœ¿çšããå Žåã®åäœæ€èšŒã«çšããã¯ã©ã¹ |
| ïŒ | Program.cs | åçš®ãã¹ã ã±ãŒã¹ãå®è¡ãããšã³ããªãã€ã³ã ã¡ãœãã |
ã¿ãŒã²ãã ã¯ã©ã¹ã¯ãæ¬æžã§èª¬æããããªããžã§ã¯ã Aãã
ããªãã¡ãã¯ã©ã€ã¢ã³ãã䜿çšããããªããžã§ã¯ãã®ããšã§ããã
å®è£
ã®ãã€ã³ãã¯ãMarshalByRefObject ã¯ã©ã¹ãç¶æ¿ããããšã§ããã
ãã®ä»ã¯ä»»æã®å®è£
ãå¯èœã§ããã
ãµã³ãã« ããã°ã©ã ã§ã¯ãæ§ã
ãªã·ã°ããã£ã®ã¡ãœããã®åŒã³åºãããã¹ãããããã«ã
æ§ã
ãªã·ã°ããã£ã®ã¡ãœãããã¿ãŒã²ãã ã¯ã©ã¹ã«å®è£
ããŠããã
- å®è£ ã®ãã€ã³ãã¯ãRealProxy ã¯ã©ã¹ãç¶æ¿ããããšã§ããã
- ãµã³ãã« ããã°ã©ã ã«ã¯ãã¢ã¹ãã¯ãã¯å®è£
ããŠããªãã®ã§ã
ä»»æã®ã¢ã¹ãã¯ãã®ãã¿ãŒã³ããããã§ãŠã£ãŒãã³ã°ããããã«å®è£ ããã
ãŸããééãããã·ïŒãïŒã§ãã³ã³ã¹ãã©ã¯ã¿ã®å®è£
ãè¥å¹²ç°ãªãã
ç°ãªãç¹ã¯ãã¿ãŒã²ãã ã¯ã©ã¹ã®ãªããžã§ã¯ã ã€ã³ã¹ã¿ã³ã¹ãçæããæ¹æ³ã§ããã
-
ééãããã·ïŒ
ã³ã³ã¹ãã©ã¯ã¿ãããã¿ãŒã²ãã ã¯ã©ã¹ã®ãªããžã§ã¯ã ã€ã³ã¹ã¿ã³ã¹ãçŽæ¥åãåãã -
ééãããã·ïŒ
ã³ã³ã¹ãã©ã¯ã¿ããã¯ã©ã¹æ å ±ãåãåãã
ããã䜿çšããŠã¿ãŒã²ãã ã¯ã©ã¹ã®ãªããžã§ã¯ã ã€ã³ã¹ã¿ã³ã¹ãçæããã
ééãããã·ïŒãïŒãšã Invoke ã¡ãœããã®å®è£ ã¯åãã§ããã
è£è¶³ïŒ
MyInt.csãåç §åãåŒæ°ã«äœ¿çšããå Žåã®åäœæ€èšŒãã®æå³ïŒ: ãã®
ãã¹ã ã±ãŒã¹ãçšæãããŠããã®ã¯ããããã·çµç±ã®åŒã³åºãã§
åŒæ°ã®æ±ããå€ãããããããšèªãããéèŠãªè«ç¹ãªã®ã§è£è¶³ããããã¢ããªã±ãŒã·ã§ã³ ãã¡ã€ã³ãè·šãå ŽåïŒæ¬æ¥ã®çšéïŒã ã»MarshalByRefObject ãç¶æ¿ããå â åç §ãæž¡ãïŒãããã·çµç±ïŒ ã»[Serializable] ãªå â ãå€ãã³ããŒããããâ ã»ã©ã¡ãã§ããªãå â äŸå€ã«ãªã â åç §åãåŒæ°ã«æž¡ããŠãããåŒã°ããåŽã§ã®å€æŽã åŒã³åºãå ã«åæ ãããªããããšããã ãåäžãã¡ã€ã³å ã§ AOP ãšããŠäœ¿ãå Žåã ã»å®éã«ã¯åãããŒãäžã®ãªããžã§ã¯ããªã®ã§ãåç §ã¯ãã®ãŸãŸæž¡ã ã»ãã ã ReturnMessage ã®äœãæ¹ã誀ããš out / ref ã®åæ ã倱ããããã®éããå®éã«ç¢ºèªãããã¹ããçšæããŠããç¹ãã
ãµã³ãã«ãšããŠæçšã§ããã
è£è¶³ïŒçŸåš .NET ã§ AOP ãå®çŸããæ¹æ³ïŒ:
RealProxyã䜿ããªã
.NET Core 以éã®éžæè¢ããŸãšããã
ææ®µ å 容 è©äŸ¡ DispatchProxyæšæº APIãã€ã³ã¿ãŒãã§ã€ã¹ã«å¯Ÿããåçãããã· â RealProxy ã®æ£çµ±ãªåŸç¶ Castle DynamicProxy ã¯ã©ã¹ã«ãé©çšå¯ïŒvirtual ã¡ãœããïŒãå®çžŸãè±å¯ æã髿©èœ DI ã³ã³ããã®ãã³ã¬ãŒã¿ãŒ Scrutorã®DecorateçåçŽæå¿« â ããã«ãŠã§ã¢ / ãã£ã«ã¿ãŒ ASP.NET Core ã®ãã€ãã©ã€ã³ Web ãªã第äžéžæ Source Generator ã³ã³ãã€ã«æã«ã©ãããŒãçæ éãïŒAOT å¯ïŒ Fody / AspectInjector IL æžãæã 匷åã ããã«ãã«ä»å ¥
DispatchProxyã®äŸïŒæšæºæ©èœã§å®çµããïŒ:public class LoggingProxy<T> : DispatchProxy where T : class { private T _target = default!; public static T Create(T target) { var proxy = Create<T, LoggingProxy<T>>() as LoggingProxy<T>; proxy!._target = target; return (proxy as T)!; } protected override object? Invoke(MethodInfo? method, object?[]? args) { Log.Information("â {Method}", method?.Name); try { return method?.Invoke(_target, args); } catch (TargetInvocationException ex) { throw ex.InnerException!; } // â finally { Log.Information("â {Method}", method?.Name); } } } // äœ¿ãæ¹ IOrderService svc = LoggingProxy<IOrderService>.Create(new OrderService());ãRealProxy ãšã®éããâ RealProxy ⊠ãã¯ã©ã¹ãã«é©çšïŒMarshalByRefObject ç¶æ¿ãå¿ èŠïŒ DispatchProxy ⊠ãã€ã³ã¿ãŒãã§ã€ã¹ãã«é©çšïŒç¶æ¿ã®å¶çŽãªãïŒ â ç¶æ¿ã®å¶çŽãæ¶ãã代ããã«ã ãã€ã³ã¿ãŒãã§ã€ã¹ãåãå¿ èŠãããã â ãã£ãšãã[DI](MS_DI) ã䜿ããªã ã€ã³ã¿ãŒãã§ã€ã¹ã¯å ã åã£ãŠããã¯ãã§ããDI ã³ã³ããã®ãã³ã¬ãŒã¿ãŒãæãçŽ çŽãªå Žåãå€ãã
// ScrutorïŒAOP ã䜿ãããçŽ çŽã«ã©ãããã services.AddScoped<IOrderService, OrderService>(); services.Decorate<IOrderService, LoggingOrderService>(); // â æç€ºç â services.Decorate<IOrderService, CachingOrderService>();ããã³ã¬ãŒã¿ãŒã®å©ç¹ã ã»ãã³ãŒããèŠãããïŒåççæã§ãªãïŒ ã»ãããã°ã§ã¹ãããå®è¡ã§ãã ã»Reflection ã®ãªãŒããŒãããããªã ã»Native AOT / ããªãã³ã°ã«å¯Ÿå¿ã§ãã â ãæ¬ ç¹ã ã»ã¡ãœããã®æ°ã ãå§è²ã³ãŒããæžãïŒå®åçã§éå±ïŒ â Source Generator ã§çæããã°è§£æ¶ããçŸåšã®å®åçãªå€æ:
â æšªæçé¢å¿äºããWeb ã®èŠæ±åäœããªã â ããã«ãŠã§ã¢ / ã¢ã¯ã·ã§ã³ ãã£ã«ã¿ãŒïŒ[ASP.NET Core](MS_ASPNETCore)ïŒ â¡ ãµãŒãã¹å±€ã«æããªã â ããã³ã¬ãŒã¿ãŒãïŒæç€ºçã§è¿œããããïŒâ ⢠察象ãå€ããå®åçãªã â DispatchProxy / Castle DynamicProxy ⣠æ§èœãæåªå ïŒAOT ãå¿ èŠãªã â Source Generator
Tags: ç§»è¡, ããã°ã©ãã³ã°, .NETéçº