How to create a SerializationBinder for the Binary Formatter that handles the moving of types from one assembly and namespace to another

你说的曾经没有我的故事 提交于 2019-11-27 09:29:09

This could work (instead of your override).

public override Type BindToType(string assemblyName, string typeName)
        {
            var m = Regex.Match(typeName, @"^(?<gen>[^\[]+)\[\[(?<type>[^\]]*)\](,\[(?<type>[^\]]*)\])*\]$");
            if (m.Success)
            { // generic type
                var gen = GetFlatTypeMapping(m.Groups["gen"].Value);
                var genArgs = m.Groups["type"]
                    .Captures
                    .Cast<Capture>()
                    .Select(c =>
                        {
                            var m2 = Regex.Match(c.Value, @"^(?<tname>.*)(?<aname>(,[^,]+){4})$");
                            return BindToType(m2.Groups["aname"].Value.Substring(1).Trim(), m2.Groups["tname"].Value.Trim());
                        })
                    .ToArray();
                return gen.MakeGenericType(genArgs);
            }
            return GetFlatTypeMapping(assemblyName,typeName);
        }

Then you just have to implement your way the function GetFlatTypeMapping (not worrying of about generic arguments).

What you will have to do is to return typeof(List<>) and typeof(Dictionary<,>) (or any other generic you would like to use) when asked.

nb: I said typeof(List<>) ! not typeof(List<something>) ... that's important.

disclaimer: because of the regex "(?[^]]*)", this snipped does not support nested generic types like List<List<string>> ... you will have to tweak it a bit to support it !

No answer

Although it might not answer your question this might solve your problem:

I was able to serialize all but one assembly required for deserialization alongside an object structure. The trick is to use reflection to inspect your object structure for types and the assemblies they are defined in. You can then write the assemblies as binary data into an object on serialization and load them into an AppDomain where you can use them to deserialize the rest of the object structure.

You have to put the AppDomain handling, the root object and some base classes into an assembly that won't change and everything else is defined in assemblies depending on this "anchor".

Upsides:

  • serialization does not break as long as the anchor assembly does not change
  • can be used for obfuscation, e.g. some required assembly can be hidden in any file
  • can be used for online updates, e.g. ship the assembly with any data
  • as far as I'm concerned no problem with generics

Downsides:

  • security issues as bootstrapping could be used to inject code (some extra work for assembly SecurityEvidences)
  • AppDomain borders are some work to cross
  • blows up your serialized data (ok, for files - bad, for communication)

But hey, communication does not break unless you have different client versions and then you can do the bootstrapping on handshake.

Sorry, I can't provide the code as it's too complex and too specific. But I share some insights in these other answers of mine:

difference between DataContract attribute and Serializable attribute in .net

Need to hookup AssemblyResolve event when DisallowApplicationBaseProbing = true

Is it a hard requirement that you MUST be using the BinaryFormatter for your de/serialization?

If it's not a hard requirement for you to be using the BinaryFormatter to do your serialization, consider alternative serialization methods, such as JSON.Net or ProtoBuf.Net. Either one of these will create platform- and version-independent serializations of your data.

Alternatively, you can perform binary serialization yourself (which is both faster and smaller than the BinaryFormatter, but generally more code-intensive as you have to be sure to write the serializer and deserializer essentially identically to each other.

If you must use BinaryFormatter, be sure to construct it with FormatterAssemblyStyle.Simple, to get around versioning problems. That tells it to not do the pedantic check of the assembly version.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!