Пример #1
0
        public static bool RemoveBinder(ITypeBinder binder)
        {
            if (binder == null)
            {
                throw new ArgumentNullException("binder");
            }

            var objectTypes = new List<Type>();

            foreach (var binderRegistration in binders)
            {
                if (binderRegistration.Value == binder)
                {
                    objectTypes.Add(binderRegistration.Key);
                }
            }

            ITypeBinder tempValue = null;

            foreach (Type objectType in objectTypes)
            {
                binders.TryRemove(objectType, out tempValue);
            }

            return tempValue != null;
        }
Пример #2
0
        /// <summary>
        /// Cam be overriden to bind this <see cref="IMessageHandler{TMessageType,TMessageContext}"/> to multiple message types.
        /// </summary>
        /// <param name="bindTarget">The binding target to bind this handler to.</param>
        protected virtual void ExtraBindings(ITypeBinder <IMessageHandler <TBaseMessageType, TMessageContext>, TBaseMessageType> bindTarget)
        {
            if (bindTarget == null)
            {
                throw new ArgumentNullException(nameof(bindTarget));
            }

            //Example: bindTarget.Bind<Derp>(this);
        }
Пример #3
0
        /// <inheritdoc />
        public void BindTo(ITypeBinder <IMessageHandler <TBaseMessageType, TMessageContext>, TBaseMessageType> bindTarget)
        {
            if (bindTarget == null)
            {
                throw new ArgumentNullException(nameof(bindTarget));
            }

            bindTarget.Bind <TMessageType>(this);

            //Allow implementers to bind this to other types too
            ExtraBindings(bindTarget);
        }
Пример #4
0
        /// <summary>
        /// Constructs the XleSerializer.  Pass in the type of the object which is
        /// the root of the object graph which needs to be serialized.  This type must
        /// implement the IXleSerializable interface.
        /// </summary>
        /// <param name="objectType">The type of the object to serialize.</param>
        public XleSerializer(Type objectType)
        {
            if (objectType.GetInterface("IXleSerializable", true) == null)
            {
                throw new ArgumentException("Object type is not IXleSerializable.");
            }

            Binder = new TypeBinder();
            (Binder as TypeBinder).AddAssembly(Assembly.GetCallingAssembly());
            (Binder as TypeBinder).SearchAssemblies.Add(Assembly.GetExecutingAssembly());

            this.objectType = objectType;
        }
Пример #5
0
        /// <summary>
        /// Sets a type binder for the provided object type.
        /// </summary>
        /// <param name="objectType">The object type.</param>
        /// <param name="binder">The type binder.</param>
        public void Set(Type objectType, ITypeBinder binder)
        {
            if (objectType == null)
            {
                throw new ArgumentNullException("objectType");
            }

            if (binder == null)
            {
                throw new ArgumentNullException("binder");
            }

            TypeBinderRegistry.SetBinder(objectType, binder);
        }
Пример #6
0
        private void DrawData(ref int rowIndex)
        {
            _controls = new List <Pair <Label, ITypeBinder> >();

            //TextBoxHint keyHint = new TextBoxHint();
            //keyHint.IsReadonly = true;

            bool showConnector = (!string.IsNullOrEmpty(_hint.ConnectorLabel));
            Dictionary <string, IEnumerable <string> > kvHints = _hint.KeyValueHints;
            ITypeBinder valueBinder = null;

            foreach (KeyValuePair <string, string> kv in _dictionary)
            {
                _overarchingPanel.RowStyles.Add(new RowStyle(SizeType.AutoSize));

                //TextBoxBinder keyBinder = new TextBoxBinder(kv.Key, keyHint);
                //_overarchingPanel.Controls.Add(keyBinder.Control, 0, rowIndex);
                Label lbl = AddLabel(kv.Key, rowIndex, 0);

                if (showConnector)
                {
                    AddLabel(_hint.ConnectorLabel, rowIndex, 1);
                }

                if (kvHints != null && kvHints.ContainsKey(kv.Key))
                {
                    valueBinder = new ComboBoxBinder(kv.Value, kvHints[kv.Key], ComboBoxStyle.DropDown);
                }
                else
                {
                    valueBinder = new TextBoxBinder(kv.Value, null);
                }
                _overarchingPanel.Controls.Add(valueBinder.Control, 2, rowIndex);

                _controls.Add(new Pair <Label, ITypeBinder>(lbl, valueBinder));
                rowIndex++;
            }
        }
Пример #7
0
        const int NewSingle  = -3;        // normal type that has no generic args

        public TypeFormatter(CerasSerializer serializer)
        {
            _serializer = serializer;
            _typeBinder = serializer.TypeBinder;
        }
Пример #8
0
 /// <summary>
 /// Removes the provided type binders.
 /// </summary>
 /// <param name="binder">The type binder.</param>
 /// <returns>true if the type binder was removed; false otherwise.</returns>
 public bool Remove(ITypeBinder binder)
 {
     return TypeBinderRegistry.RemoveBinder(binder);
 }
        /// <summary>
        /// Gets a value from the associated <see cref="ITypeBinder"/> object.
        /// </summary>
        /// <param name="context">The service context.</param>
        /// <param name="parameter">The service method parameter.</param>
        /// <param name="typeBinder">The associated type binder.</param>
        /// <returns>The parameter value.</returns>
        protected virtual object GetTypeBindedValue(IServiceContext context, ParameterInfo parameter, ITypeBinder typeBinder)
        {
            if (parameter == null)
            {
                throw new ArgumentNullException("parameter");
            }

            if (typeBinder == null)
            {
                throw new ArgumentNullException("typeBinder");
            }

            if (context == null)
            {
                throw new ArgumentNullException("context");
            }

            object value = typeBinder.Bind(parameter.Name, parameter.ParameterType, context);

            if (value == null && parameter.DefaultValue != DBNull.Value)
            {
                return parameter.DefaultValue;
            }

            return value;
        }
Пример #10
0
        /// <summary>
        /// Creates a new CerasSerializer, be sure to check out the tutorial.
        /// </summary>
        public CerasSerializer(SerializerConfig config = null)
        {
            Config = config ?? new SerializerConfig();

            if (Config.ExternalObjectResolver == null)
            {
                Config.ExternalObjectResolver = new ErrorResolver();
            }

            if (Config.Advanced.UseReinterpretFormatter && Config.VersionTolerance.Mode != VersionToleranceMode.Disabled)
            {
                throw new NotSupportedException("You can not use 'UseReinterpretFormatter' together with version tolerance. Either disable version tolerance, or use the old formatter for blittable types by setting 'Config.Advanced.UseReinterpretFormatter' to false.");
            }

            if (Config.Advanced.AotMode != AotMode.None && Config.VersionTolerance.Mode != VersionToleranceMode.Disabled)
            {
                throw new NotSupportedException("You can not use 'AotMode.Enabled' and version tolerance at the same time for now. If you would like this feature implemented, please open an issue on GitHub explaining your use-case, or join the Discord server.");
            }

            TypeBinder          = Config.Advanced.TypeBinder ?? new NaiveTypeBinder();
            DiscardObjectMethod = Config.Advanced.DiscardObjectMethod;

            _userResolvers = Config.OnResolveFormatter.ToArray();

            // Int, Float, Enum, ...
            _resolvers.Add(new PrimitiveResolver(this));

            // Fast native copy for unmanaged types;
            // can not handle generic structs like ValueTuple<> because they always have to be ".IsAutoLayout"
            _resolvers.Add(new ReinterpretFormatterResolver(this));

            // DateTime, Guid, KeyValuePair, Tuple, ...
            _resolvers.Add(new StandardFormatterResolver(this));

            // Array, List, Dictionary, ICollection<T>, ...
            _resolvers.Add(new CollectionFormatterResolver(this));

            // String Formatter should never be wrapped in a RefFormatter, that's too slow and not necessary
            IFormatter stringFormatter;

            if (Config.Advanced.SizeLimits.MaxStringLength < uint.MaxValue)
            {
                stringFormatter = new MaxSizeStringFormatter(Config.Advanced.SizeLimits.MaxStringLength);
            }
            else
            {
                stringFormatter = new StringFormatter();
            }
            InjectDependencies(stringFormatter);
            SetFormatters(typeof(string), stringFormatter, stringFormatter);

            //
            // Type formatter is the basis for all complex objects,
            // It is special and has its own caching system (so no wrapping in a ReferenceFormatter)
            var typeFormatter = new TypeFormatter(this);

            var runtimeType = GetType().GetType();

            SetFormatters(typeof(Type), typeFormatter, typeFormatter);
            SetFormatters(runtimeType, typeFormatter, typeFormatter);

            // MemberInfos (FieldInfo, RuntimeFieldInfo, ...)
            _resolvers.Add(new ReflectionFormatterResolver(this));

            // DynamicObjectResolver is a special case, so it is not in the resolver-list
            // That is because we only want to have specific resolvers in the resolvers-list
            _dynamicResolver = new DynamicObjectFormatterResolver(this);

            // System.Linq.Expressions - mostly handled by special configurations and DynamicFormatter, but there are some special cases.
            _resolvers.Add(new ExpressionFormatterResolver());


            //
            // Basic setup is done
            // Now calculate the protocol checksum
            _knownTypes = Config.KnownTypes.ToArray();
            if (Config.KnownTypes.Distinct().Count() != _knownTypes.Length)
            {
                // We want a *good* error message. Simply saying "can't contain any type multiple times" is not enough.
                // We have to figure out which types are there more than once.
                HashSet <Type> hashSet         = new HashSet <Type>();
                List <Type>    foundDuplicates = new List <Type>();

                for (int i = 0; i < _knownTypes.Length; i++)
                {
                    var t = _knownTypes[i];
                    if (!hashSet.Add(t))
                    {
                        if (!foundDuplicates.Contains(t))
                        {
                            foundDuplicates.Add(t);
                        }
                    }
                }

                var duplicateTypesStr = string.Join(", ", foundDuplicates.Select(t => t.Name));

                throw new Exception("KnownTypes can not contain any type multiple times! Your KnownTypes collection contains the following types more than once: " + duplicateTypesStr);
            }

            //
            // Generate checksum
            {
                foreach (var t in _knownTypes)
                {
                    ProtocolChecksum.Add(t.FullName);

                    if (t.IsEnum)
                    {
                        // Enums are a special case, they are classes internally, but they only have one field ("__value")
                        // We're always serializing them in binary with their underlying type, so there's no reason changes like Adding/Removing/Renaming
                        // enum-members could ever cause any binary incompatibility
                        //
                        // A change in the base-type however WILL cause problems!
                        ProtocolChecksum.Add(t.GetEnumUnderlyingType().FullName);
                        continue;
                    }

                    if (!t.ContainsGenericParameters)
                    {
                        var meta = GetTypeMetaData(t);
                        if (meta.PrimarySchema != null)
                        {
                            foreach (var m in meta.PrimarySchema.Members)
                            {
                                ProtocolChecksum.Add(m.MemberType.FullName);
                                ProtocolChecksum.Add(m.MemberName);

                                foreach (var a in m.MemberInfo.GetCustomAttributes(true))
                                {
                                    ProtocolChecksum.Add(a.ToString());
                                }
                            }
                        }
                    }
                }

                ProtocolChecksum.Finish();
            }

            //
            // We can already pre-warm formatters
            // - dynamic serializers generate their code
            // - reference formatters generate their wrappers
            foreach (var t in _knownTypes)
            {
                if (!t.ContainsGenericParameters)
                {
                    GetReferenceFormatter(t);
                }
            }



            //
            // Finally we need "instance data"
            _instanceDataPool = new FactoryPool <InstanceData>(p =>
            {
                var d                    = new InstanceData();
                d.CurrentRoot            = null;
                d.ObjectCache            = new ObjectCache();
                d.TypeCache              = new TypeCache(_knownTypes);
                d.EncounteredSchemaTypes = new HashSet <Type>();

                return(d);
            });
            InstanceData = _instanceDataPool.RentObject();

            if (Config.Advanced.SealTypesWhenUsingKnownTypes)
            {
                if (_knownTypes.Length > 0)
                {
                    typeFormatter.Seal();
                }
            }
        }
Пример #11
0
 public TypeFormatter(CerasSerializer ceras)
 {
     _ceras      = ceras;
     _typeBinder = ceras.TypeBinder;
 }
Пример #12
0
 public static void SetBinder(Type objectType, ITypeBinder binder)
 {
     binders.AddOrUpdate(objectType, type => binder, (type, previousFormatter) => binder);
 }