Пример #1
0
        public void TypeNameTest()
        {
            // primitive type
            string typeName = TypeResolutionHelper.RemoveAssemblyName(typeof(int).AssemblyQualifiedName);

            Assert.AreEqual(typeof(int).FullName, typeName);
            Assert.AreEqual(typeof(int), Type.GetType(typeName));

            typeName = TypeResolutionHelper.RemoveAssemblyName(typeof(int[]).AssemblyQualifiedName);
            Assert.AreEqual(typeof(int[]).FullName, typeName);
            Assert.AreEqual(typeof(int[]), Type.GetType(typeName));

            typeName = TypeResolutionHelper.RemoveAssemblyName(typeof(int[, ]).AssemblyQualifiedName);
            Assert.AreEqual(typeof(int[, ]).FullName, typeName);
            Assert.AreEqual(typeof(int[, ]), Type.GetType(typeName));

            typeName = TypeResolutionHelper.RemoveAssemblyName(typeof(string).AssemblyQualifiedName);
            Assert.AreEqual(typeof(string).FullName, typeName);
            Assert.AreEqual(typeof(string), Type.GetType(typeName));

            typeName = TypeResolutionHelper.RemoveAssemblyName(typeof(object).AssemblyQualifiedName);
            Assert.AreEqual(typeof(object).FullName, typeName);
            Assert.AreEqual(typeof(object), Type.GetType(typeName));

            typeName = TypeResolutionHelper.RemoveAssemblyName(typeof(byte *).AssemblyQualifiedName);
            Assert.AreEqual(typeof(byte *).FullName, typeName);
            Assert.AreEqual(typeof(byte *), Type.GetType(typeName));

            typeName = TypeResolutionHelper.RemoveAssemblyName(typeof(List <>).AssemblyQualifiedName);
            Assert.AreEqual(typeof(List <>).FullName, typeName);
            Assert.AreEqual(typeof(List <>), Type.GetType(typeName));

            // Note - Type.FullName does not remove the AQN from the inner type parameters of generic
            // types, so we won't test the result for equality with typeof(List<int>).FullName
            typeName = TypeResolutionHelper.RemoveAssemblyName(typeof(List <int>).AssemblyQualifiedName);
            Assert.AreEqual(typeof(List <int>), Type.GetType(typeName));

            typeName = TypeResolutionHelper.RemoveAssemblyName(typeof(IEnumerable <int>).AssemblyQualifiedName);
            Assert.AreEqual(typeof(IEnumerable <int>), Type.GetType(typeName));

            typeName = TypeResolutionHelper.RemoveAssemblyName(typeof(IDictionary <int, List <int> >).AssemblyQualifiedName);
            Assert.AreEqual(typeof(IDictionary <int, List <int> >), Type.GetType(typeName));

            typeName = TypeResolutionHelper.RemoveAssemblyName(typeof(Func <int, double>).AssemblyQualifiedName);
            Assert.AreEqual(typeof(Func <int, double>), Type.GetType(typeName));

            typeName = TypeResolutionHelper.RemoveAssemblyName(typeof(NestedClass <List <int> >).AssemblyQualifiedName);
            Assert.AreEqual(typeof(NestedClass <List <int> >), Type.GetType(typeName));

            typeName = TypeResolutionHelper.RemoveAssemblyName("Namespace.TypeName, AssemblyName WithSpaces-v1.0.0.0, Version=1.0.0.0");
            Assert.AreEqual("Namespace.TypeName", typeName);

            typeName = TypeResolutionHelper.RemoveAssemblyName("Namespace.TypeName`2[[Nested.TypeName1, AssemblyName WithSpaces-v1.0.0.0, Version=1.0.0.0], [Nested.TypeName2[], AssemblyName, Culture=neutral]], AssemblyName, PublicKeyToken=null");
            Assert.AreEqual("Namespace.TypeName`2[[Nested.TypeName1], [Nested.TypeName2[]]]", typeName);
        }
Пример #2
0
        /// <summary>
        /// Creates and registers a handler for the specified type according to the rules added so far.
        /// </summary>
        /// <typeparam name="T">The type being serialized.</typeparam>
        /// <returns>The newly created handler.</returns>
        private SerializationHandler AddHandler <T>()
        {
            SerializationHandler handler = null;
            var             type         = typeof(T);
            ISerializer <T> serializer   = null;
            TypeSchema      schema       = null;

            if (!this.knownNames.TryGetValue(type, out string name))
            {
                name = TypeSchema.GetContractName(type, this.runtimeVersion);
            }

            if (!this.schemas.TryGetValue(name, out schema))
            {
                // try to match to an existing schema without assembly/version info
                string typeName = TypeResolutionHelper.RemoveAssemblyName(type.AssemblyQualifiedName);
                schema = this.schemas.Values.FirstOrDefault(s => TypeResolutionHelper.RemoveAssemblyName(s.TypeName) == typeName);
            }

            int id = schema?.Id ?? TypeSchema.GetId(name);

            serializer = this.CreateSerializer <T>();
            handler    = SerializationHandler.Create <T>(serializer, schema?.Name ?? name, id);

            // first register the handler
            int oldCount    = this.handlers.Length;
            var newHandlers = new SerializationHandler[oldCount + 1];

            Array.Copy(this.handlers, newHandlers, oldCount);
            newHandlers[oldCount] = handler;
            this.handlers         = newHandlers;

            var newIndex = new Dictionary <SerializationHandler, int>(this.index);

            newIndex[handler] = oldCount;
            this.index        = newIndex;

            var newHandlersByType = new Dictionary <Type, SerializationHandler>(this.handlersByType);

            newHandlersByType[type] = handler;
            this.handlersByType     = newHandlersByType;

            var newHandlersById = new Dictionary <int, SerializationHandler>(this.handlersById);

            newHandlersById[handler.Id] = handler;
            this.handlersById           = newHandlersById;

            // find the schema for this serializer (can be null for interfaces)
            if (serializer != null)
            {
                // initialize the serializer after the handler is registered,
                // to make sure all handlers are registered before initialization runs and
                // allow the serializer initialization code to find and cache the handlers for the types it needs
                schema = serializer.Initialize(this, schema);

                // let any subscribers know that we initialized a new serializer that publishes a schema
                if (schema != null)
                {
                    // store the updated schema and override whatever is present already
                    this.schemas[schema.Name]   = schema;
                    this.schemasById[schema.Id] = schema;
                    this.SchemaAdded?.Invoke(this, schema);
                }
            }

            return(handler);
        }