ã¯ããã« åé¡ã®å£°æ
å°è³ªåŠã®åéã§åã倧äŒæ¥ãšååããŠããŸãã æŽå²çã«ãäŒæ¥ã¯ãããŸããŸãªã¿ã€ãã®æ©åš+ããŒã¿åæ+äºæž¬ããã®ããŒã¿ãåŠçããããã®éåžžã«ç°ãªããœãããŠã§ã¢ãäœæããŠããŸããã æ®å¿µãªããããã®ãœãããŠã§ã¢ã¯ãã¹ãŠäºãã«åžžã«ãå奜çããšã¯ã»ã©é ãããŸã£ããå奜çã§ã¯ãããŸããã äœããã®æ¹æ³ã§æ å ±ãçµ±åããããã«ãããŸããŸãªããã°ã©ã ãããŒã¿ãxml圢åŒã§ã¢ããããŒãããWebããŒã¿ã«ãäœæãããŠããŸãã ãããŠãããŒã¿ã«ã¯ãã©ã¹ãã€ãã¹å®å šãªãã¥ãŒãäœæããããšããŠããŸãã éèŠãªãã¥ã¢ã³ã¹ïŒããŒã¿ã«ã®éçºè ã¯åã¢ããªã±ãŒã·ã§ã³ã®ãµããžã§ã¯ãé åã«ç²ŸéããŠããªããããåããŒã ã¯XMLããããŒã¿ã«ããŒã¿æ§é ãžã®ããŒãµãŒ/ããŒã¿ã³ã³ããŒã¿ãŒã¢ãžã¥ãŒã«ãæäŸããŸããã
ç§ã¯ã¢ããªã±ãŒã·ã§ã³ã®1ã€ãéçºããããŒã ã§åããŠãããããŒã¿ã®ãšã¯ã¹ããŒãã¡ã«ããºã ãéåžžã«ç°¡åã«èšè¿°ããŸããã ããããããã§ãããžãã¹ã¢ããªã¹ãã¯ãäžå€®ããŒã¿ã«ã§ããã°ã©ã ãäœæããã¬ããŒãã®1ã€ãå¿ èŠã§ãããšå€æããŸããã ãããæåã®åé¡ãçºçããå Žæã§ããã¬ããŒãã¯æ¯åäœæãããçµæã¯ã©ãã«ãä¿åãããŸããã
ãä¿åããŠãã ããïŒãèªè ã¯ããããèããã§ãããã ç§ãããæã£ãŠããŸããããããŠã³ããŒãããããŒã¿ã®ã¬ããŒãããã§ã«äœæããå¿ èŠãããããšã«çå£ã«å€±æããŸããã äœãããå¿ èŠã¯ãããŸãã-ããžãã¯ã転éããå¿ èŠããããŸãã
ã¹ããŒãž0ããªãã¡ã¯ã¿ãªã³ã°ã ãã©ãã«ã®åå ã¯ãªã
ã¬ããŒããæ§ç¯ããããžãã¯ïŒå®éãããã¯4åã®ã©ãã«ã§ãããããžãã¯ã¯ãã£ãªããžãšå€§ããªã«ãŒãã§ãïŒãå¥ã®ã¯ã©ã¹ã«åé¢ããããŒãµãŒã¢ã»ã³ããªå ã®åç §ã«ãã£ãŠãã®ã¯ã©ã¹ã®ãã¡ã€ã«ãå«ããããšã決å®ãããŸããã ããã«ããïŒ
- çŽæ¥ã³ããŒãé¿ãã
- ããŒãžã§ã³ã®äžäžèŽããä¿è·ãã
ããžãã¯ãå¥ã®ã¯ã©ã¹ã«åé¢ããã®ã¯é£ããäœæ¥ã§ã¯ãããŸããã ãããããã¹ãŠãããã»ã©ãã©è²ã§ã¯ãããŸããã§ãããã¢ã«ãŽãªãºã ã¯ããžãã¹ãªããžã§ã¯ãã«åºã¥ããŠããããã®è»¢éã¯æŠå¿µã«é©åããŸããã§ããã ã¡ãœãããæžãæããŠãåçŽãªåã®ã¿ãåãå ¥ããŠæäœããããã«ããŸããã ããã¯å¿ ãããåçŽã§ã¯ãªããå Žæã«ãã£ãŠã¯æ±ºå®ãå¿ èŠã§ããããã®çŸããã¯åé¡ã®ãŸãŸã§ããããäžè¬ã«ãä¿¡é Œã§ãã解決çã¯æãããªæŸèæãªãã§åŸãããŸããã
ãåãã®ããã«ãæªéã®å± å¿å°ã®è¯ãé ã家ãšããŠåœ¹ç«ã€ããšããã詳现ã1ã€ãããŸãããã¬ããŒããäœæããããã«å¿ èŠãªããŒã¿ã®äžéšããã€ããªã·ãªã¢ã«åããã.Netãªããžã§ã¯ããšããŠããŒã¿ããŒã¹ã«ä¿åããããåäžä»£ã®éçºè ããå¥åŠãªã¢ãããŒããç¶æ¿ããŸããïŒ ããªãïŒãããkaaakïŒããªã©ã®è³ªåã¯ãå®å ãäžè¶³ããŠããããæªåçã®ãŸãŸã«ãªããŸãïŒã ãããŠãèšç®ã®å ¥åã§ã¯ããã¡ãããããããéã·ãªã¢ã«åããå¿ èŠããããŸãã
ãããã®ã¿ã€ãã¯ãåãé€ãããšã¯äžå¯èœã§ããããç¹ã«è€éã§ã¯ãªãããããåç §ã«ãããããšãå«ããŸããã
ã¹ããŒãž1.ãã·ãªã¢ã©ã€ãŒãŒã·ã§ã³ã å®å šãªã¿ã€ãåãèŠããŠãããŠãã ãã
äžèšã®æäœãè¡ã£ãŠãã¹ããå®è¡ããåŸãäºæããã©ã³ã¿ã€ã ãšã©ãŒãçºçããŸããã
[A] Namespace.TypeAã¯[B] Namespace.TypeAã«ãã£ã¹ãã§ããŸããã ã¿ã€ãAã¯ããAssembley.ApplicationãVersion = 1.0.0.0ãCulture = neutralãPublicKeyToken = nullãã«ç±æ¥ããã³ã³ããã¹ããDefaultãã®å Žæã...ãã«ãããŸãã ã¿ã€ãBã¯ãå Žæ ''ã®ã³ã³ããã¹ã 'Default'ã® 'Assmbley.PortalãVersion = 1.0.0.0ãCulture = neutralãPublicKeyToken = null'ããçºçããŸããæåã®Googleãªã³ã¯ãããBinaryFormatterãããŒã¿ã ãã§ãªããè«ççãªåºåã¹ããªãŒã ã«åæ å ±ãæžã蟌ããšããäºå®ãããããšãããããŸããã ãããŠãåã®ãã«ããŒã ã宣èšãããã¢ã»ã³ããªãå«ãããšãèãããšã1ã€ã®åããã·ãªã¢ã©ã€ãºããããšãããã®ã®çµµã¯ã.Netã®èŠ³ç¹ãšã¯ãŸã£ããç°ãªããŸã
ç§ã¯é ã®åŸããã²ã£ãããã®ã§ãããŸããŸããã·ãªã¢ã©ã€ãºäžã«ç¹å®ã®TypeAã¿ã€ããdynamicã«çœ®ãæãããšããæãããªããããæ®å¿µãªæªæã®ãã決å®ãäžããŸããã ãã¹ãŠãããŸããããŸããã ã¬ããŒãã®çµæã¯æ¬¡ã ãšåæãããã«ããµãŒããŒã§ã®ãã¹ãã«åæ ŒããŸããã éææãæã£ãŠãã¿ã¹ã¯ããã¹ã¿ãŒã«ââéããŸãã
ã¹ããŒãž2ãã¡ã€ã³ã ã¢ã»ã³ããªéã®ã·ãªã¢ã«å
èšç®ã¯ãã¹ã¿ãŒã«ââãã£ãŠç»é²ããããã°ã®åœ¢ã§ããã«èµ·ãããŸãããããã¯ãã¢ã»ã³ããªAssembley.ApplicationïŒã¢ããªã±ãŒã·ã§ã³ããã®ã¢ã»ã³ããªïŒãèªã¿èŸŒãããšãã§ããªããšããäŸå€ãé€ããŠãããŒã¿ã«åŽã®ããŒãµãŒãèœã¡ããšè¿°ã¹ãŸããã æåã«èãã-ç§ã¯åç §ããããã«ããŸããã§ããã ããã-ãããããã¹ãŠãããŸãããã誰ãèšåããŸããã ãµã³ãããã¯ã¹ã§ããäžåºŠå®è¡ããŠã¿ãŸã-ãã¹ãŠãæ©èœããŸãã ãã«ããšã©ãŒãçãããããã«ãªããŸããããããã§ç§ãåã°ããªãã¢ã€ãã¢ãæµ®ãã³ãŸãããããŒãµãŒã®åºåãã¹ããã¢ããªã±ãŒã·ã§ã³ã®å ±æbinãã£ã¬ã¯ããªã§ã¯ãªããå¥ã®ãã©ã«ããŒã«å€æŽããŸãã ãããŠåºæ¥äžãã-ç§ã¯èª¬æãããäŸå€ãååŸããŸãã Stectraceåæã¯ææ§ãªæšæž¬ã確èªããŸã-ãã·ãªã¢ã©ã€ãŒãŒã·ã§ã³ã¯äœäžããŠããŸãã
ç¹å®ã®åãåçã«çœ®ãæããŠãäœãå€ãããŸããã§ãããBinaryFormatterã¯å€éšã¢ã»ã³ããªããåãäœæããŸãããåãæã€ã¢ã»ã³ããªãè¿ãã«ãããã©ã³ã¿ã€ã ãèªç¶ã«ããŒãããã¢ã»ã³ããªããªããªã£ãå Žåã®ã¿ã§ãããšã©ãŒãçºçããŸãã
æ²ããçç±ããããŸããã ããããã°ãŒã°ã«ã¯SerializationBinderã¯ã©ã¹ã®åœ¢ã§åžæãäžããŸããã å€æããããã«ãããŒã¿ãéã·ãªã¢ã«åããã¿ã€ãã決å®ã§ããŸãã ãããè¡ãã«ã¯ãçžç¶äººãäœæãã次ã®ã¡ãœãããå®çŸ©ããŸãã
public abstract Type BindToType(String assemblyName, String typeName);
ç¹å®ã®æ¡ä»¶ã«å¯ŸããŠä»»æã®åãè¿ãããšãã§ããŸãã
BinaryFormatterã¯ã©ã¹ã«ã¯ãå®è£ ãæ¿å ¥ã§ããBinderããããã£ããããŸãã
åé¡ãªããšæãããŸãã ããããããã§ã詳现ã¯æ®ã£ãŠããŸãïŒäžèšåç §ïŒã
ãŸãã ãã¹ãŠã®ã¿ã€ãïŒããã³æšæºïŒã®ãªã¯ãšã¹ããåŠçããå¿ èŠããããŸãã
ããã§èå³æ·±ãå®è£ ãªãã·ã§ã³ãã€ã³ã¿ãŒãããäžã§èŠã€ãããŸãããã圌ãã¯BinaryFormatterããããã©ã«ãã®ãã€ã³ããŒãæ§ç¯ã®åœ¢ã§äœ¿çšããããšããŠããŸãããã«èŠåŽããã«ãç§ã¯èªåèªèº«ã§åãè«çãç¹°ãè¿ããŸããã
var defaultBinder = new BinaryFormatter().Binder
ããããå®éã«ã¯ããã€ã³ããŒããããã£ã¯ããã©ã«ãã§nullã§ãã ãœãŒã¹ã³ãŒãã®åæã«ãããBinaryFormatterå ã§ã¯ãBinderããã§ãã¯ããããã©ããããã§ãã¯ãããå Žåããã®ã¡ãœãããåŒã³åºããããã§ãã¯ãããªãå Žåãå éšããžãã¯ã䜿çšãããæçµçã«ã¯
var assembly = Assembly.Load(assemblyName); return FormatterServices.GetTypeFromAssembly(assembly, typeName);
ãããæåã®å®è£ ã§èµ·ãã£ãããšã§ã
public class MyBinder : SerializationBinder { public override Type BindToType(string assemblyName, string typeName) { if (assemblyName.Contains("<ObligatoryPartOfNamespace>") ) { var bindToType = Type.GetType(typeName); return bindToType; } else { var bindToType = LoadTypeFromAssembly(assemblyName, typeName); return bindToType; } } private Type LoadTypeFromAssembly(string assemblyName, string typeName) { if (string.IsNullOrEmpty(assemblyName) || string.IsNullOrEmpty(typeName)) return null; var assembly = Assembly.Load(assemblyName); return FormatterServices.GetTypeFromAssembly(assembly, typeName); } }
ã€ãŸã åå空éããããžã§ã¯ãã«å±ããŠãããã©ããã確èªãããŸã-çŸåšã®ãã¡ã€ã³ããåãè¿ããã·ã¹ãã ã®åã§ããã°ã察å¿ããã¢ã»ã³ããªããèªã¿èŸŒã¿ãŸã
è«ççã«èŠããŸãã ç§ãã¡ã¯ãã¹ããéå§ããŸãïŒç§ãã¡ã®ã¿ã€ããæ¥ã-ç§ãã¡ã¯çœ®ãæãããããäœæãããŸãã ãã£ãïŒ æååãæ¥ã-ã¢ã»ã³ããªããããŒãããªãããã©ã³ãã«æ²¿ã£ãŠé²ã¿ãŸãã ããŸãããïŒ ããŒãã£ã«ã·ã£ã³ãã³ãéã...
ããããããã«...èŸæžã«ã¯ãŠãŒã¶ãŒã¿ã€ãã®èŠçŽ ãå«ãŸããŠããŸãïŒããã¯ã·ã¹ãã ã¿ã€ããªã®ã§ã...æããã«ãã¢ã»ã³ããªããããŒãããããšããŠããŸãããèŠçŽ ã¯ç§ãã¡ã®ã¿ã€ãã§ãããå®å šä¿®é£ŸïŒã¢ã»ã³ããªãããŒãžã§ã³ãããŒïŒãããããåã³èœã¡ãŸãã ïŒæ²ããç¬é¡ãããã¯ãã§ãïŒã
æããã«ãåã®å ¥ååãå€æŽããŠãç®çã®ã¢ã»ã³ããªãžã®ãªã³ã¯ã眮ãæããå¿ èŠããããŸãã ååã«ã¯ã AssemblyNameã¯ã©ã¹ã®é¡äŒŒç©ãããããšãæ¬åœã«æã¿ãŸããããé¡äŒŒãããã®ã¯èŠã€ãããŸããã§ããã 眮æã䌎ããŠãããŒãµã«ããŒãµãŒã®äœæã¯ç°¡åãªäœæ¥ã§ã¯ãããŸããã äžé£ã®å®éšã®åŸã次ã®è§£æ±ºçã«è¡ããŸããïŒéçã³ã³ã¹ãã©ã¯ã¿ãŒã§ã眮ãæããåãæžç®ããäœæãããåã®ååãæã€è¡ã§ååãæ¢ããèŠã€ãã£ããã¢ã»ã³ããªåã眮ãæããŸã
/// <summary> /// The types that may be changed to local /// </summary> protected static IEnumerable<Type> _changedTypes; static MyBinder() { var executingAssembly = Assembly.GetCallingAssembly(); var name = executingAssembly.GetName().Name; _changedTypes = executingAssembly.GetTypes().Where(t => t.Namespace != null && !t.Namespace.Contains(name) && !t.Name.StartsWith("<")); //!t.Namespace.Contains(name) - . , // "<' - } private static string CorrectTypeName(string name) { foreach (var changedType in _changedTypes) { var ind = name.IndexOf(changedType.FullName); if (ind != -1) { var endIndex = name.IndexOf("PublicKeyToken", ind) ; if (endIndex != -1) { endIndex += +"PublicKeyToken".Length + 1; while (char.IsLetterOrDigit(name[endIndex++])) { } var sb = new StringBuilder(); sb.Append(name.Substring(0, ind)); sb.Append(changedType.AssemblyQualifiedName); sb.Append(name.Substring(endIndex-1)); name = sb.ToString(); } } } return name; } /// <summary> /// look up the type locally if the assembly-name is "NA" /// </summary> /// <param name="assemblyName"></param> /// <param name="typeName"></param> /// <returns></returns> public override Type BindToType(string assemblyName, string typeName) { typeName = CorrectTypeName(typeName); if (assemblyName.Contains("<ObligatoryPartOfNamespace>") || assemblyName.Equals("NA")) { var bindToType = Type.GetType(typeName); return bindToType; } else { var bindToType = LoadTypeFromAssembly(assemblyName, typeName); return bindToType; } }
ã芧ã®ãšãããPublicKeyTokenãåã®èª¬æã®æåŸã§ãããšããäºå®ããå§ããŸããã ããããããã¯100ïŒ ä¿¡é Œã§ãããã®ã§ã¯ãããŸããããç§ã®ãã¹ãã§ã¯ãããã§ãªãå Žåã¯èŠã€ãããŸããã§ããã
ãããã£ãŠã次ã®åœ¢åŒã®è¡
"System.Collections.Generic.Dictionary`2 [[SomeNamespace.CustomTypeãAssembley.ApplicationãVersion = 1.0.0.0ãCulture = neutralãPublicKeyToken = null]ã[System.Byte []ãmscorlibãVersion = 4.0.0.0ãã«ã«ãã£ãŒ=ãã¥ãŒãã©ã«ãPublicKeyToken = b77a5c561934e089]]»
ã«ãªããŸã
"System.Collections.Generic.Dictionary`2 [[SomeNamespace.CustomTypeãAssembley.PortalãVersion = 1.0.0.0ãCulture = neutralãPublicKeyToken = null]ã[System.Byte []ãmscorlibãVersion = 4.0.0.0ãã«ã«ãã£ãŒ=ãã¥ãŒãã©ã«ãPublicKeyToken = b77a5c561934e089]]»
ä»ã§ã¯ãã¹ãŠããæèšã®ããã«ãæçµçã«æ©èœããŸããã æè¡çãªåŸ®åŠãªåŸ®åŠãªç¹ãæ®ã£ãŠããŸããèŠããŠãããªããç§ãã¡ãå«ãããã¡ã€ã«ã¯ã¡ã€ã³ã¢ããªã±ãŒã·ã§ã³ããã®ãªã³ã¯ã«å«ãŸããŠããŸããã ããããã¡ã€ã³ã¢ããªã±ãŒã·ã§ã³ã§ã¯ãããããã¹ãŠã®ãã³ã¹ã¯å¿ èŠãããŸããã ãããã£ãŠã次ã®åœ¢åŒã®æ¡ä»¶ä»ãã³ã³ãã€ã«ã¡ã«ããºã
BinaryFormatter binForm = new BinaryFormatter(); #if EXTERNAL_LIB binForm.Binder = new MyBinder(); #endif
ãããã£ãŠãããŒã¿ã«ã¢ã»ã³ããªã§ã¯ãã¯ãEXTERNAL_LIBãå®çŸ©ããŸãããã¡ã€ã³ã¢ããªã±ãŒã·ã§ã³ã§ã¯-ããã
ãéåæ çãªäœè«ã
å®éãã³ãŒãã£ã³ã°ã®éçšã§ã解決çããã°ãã確èªããããã«ã1ã€ã®èšç®ãã¹ãããŸãããããã«ãããããããäžå®æ°ã®ç¥çµçŽ°èãç ç²ã«ãªããŸããããŸããDicitionaryã®å眮æãããŒãã³ãŒãã£ã³ã°ããŸããã ãã®çµæãéã·ãªã¢ã«åã®åŸã空ã®ãã£ã¯ã·ã§ããªãåŸãããŸããããã®ãã£ã¯ã·ã§ããªã¯ãããã€ãã®æäœãå®è¡ããããšãããšãã¯ã©ãã·ã¥ãããŸããã BinaryFormatterã欺ãããšã¯ã§ããªããšæ¢ã«èãå§ããŠããã®ã§ãèŸæžã®çžç¶äººãæžãè©Šã¿ã§å¿ æ»ã®å®éšãå§ããŸããã 幞ããªããšã«ãç§ã¯ã»ãŒå®å»ã«åæ¢ããæ®éçãªä»£æ¿ã¡ã«ããºã ã®äœæã«æ»ãããããå®è£ ããŠãèŸæžãäœæããã ãã§ã¯ãã®åãåå®çŸ©ããã ãã§ã¯äžååã§ããããšã«æ°ä»ããŸããããã€ã³ããŒ
ãããã¯ãã€ããªã·ãªã¢ã«åã®åéºã§ãã ãã£ãŒãããã¯ã«æè¬ããŸãã