コード例 #1
0
        /// <summary>
        /// Initializes a new instance of the <see cref="ObcSerializerBase"/> class.
        /// </summary>
        /// <param name="serializationConfigurationType">The serialization configuration type to use.</param>
        protected ObcSerializerBase(
            SerializationConfigurationType serializationConfigurationType)
        {
            if (serializationConfigurationType == null)
            {
                throw new ArgumentNullException(nameof(serializationConfigurationType));
            }

            this.SerializationConfigurationType = serializationConfigurationType;
            this.SerializationConfiguration     = SerializationConfigurationManager.GetOrAddSerializationConfiguration(serializationConfigurationType);
        }
コード例 #2
0
        /// <summary>
        /// Gets an existing, fully initialized serialization configuration or creates and fully initializes a new one if
        /// one does not already exist for the specified serialization configuration type.
        /// </summary>
        /// <param name="serializationConfigurationType">The serialization configuration type.</param>
        /// <returns>
        /// An initialized instance of the specified serialization configuration type.
        /// </returns>
        public static SerializationConfigurationBase GetOrAddSerializationConfiguration(
            SerializationConfigurationType serializationConfigurationType)
        {
            if (serializationConfigurationType == null)
            {
                throw new ArgumentNullException(nameof(serializationConfigurationType));
            }

            var result = GetOrAddInstance(serializationConfigurationType);

            return(result);
        }
コード例 #3
0
        private static void SeedAncestorsAndDescendants(
            SerializationConfigurationType serializationConfigurationType)
        {
            var serializationConfigurationConcreteType = serializationConfigurationType.ConcreteSerializationConfigurationDerivativeType;

            var assembliesToProcess = new HashSet <Assembly> {
                serializationConfigurationConcreteType.Assembly
            };

            // The universe of types that we are interested in are scoped to the dependency tree of assemblies of the serialization
            // configuration type's assembly.  The serialization configuration will depend on other serialization configuration
            // types and on domain types, which themselves will depend on other serialization configuration and domain types, and so on.
            assembliesToProcess.AddRange(GetRecursivelyReferencedAssemblies(serializationConfigurationConcreteType.Assembly));

            // However, when the serialization configuration type is NOT in-subsystem, then there's the potential to miss some
            // assemblies.  For example, lets say the consumer uses TypesToRegisterBsonSerializationConfiguration<T> and specifies
            // a T in their sub-system.  TypesToRegisterBsonSerializationConfiguration<MyType> is in the OBC.Serialization.Bson assembly
            // and using the heuristic above, we won't traverse T's assembly.  So this code recursively unpacks the generic arguments
            // (if any) of the serialization configuration type and adds the assemblies of those types to the list of assemblies to process.
            // One flaw with this approach is that the consumer could have created their own non-generic "wrapper" serialization configuration
            // in some assembly other than an assembly in the sub-system in question.  For example, they could create a class
            // MyTypeToRegisterBsonSerializationConfiguration with a constructor that takes parameter of type Type.
            // So there's certainly an improvement that could be made to the code below that inspects all of the types referenced
            // by the serialization configuration type and not just the generic parameter types.
            assembliesToProcess.AddRange(GetRecursiveGenericArgumentAssemblies(serializationConfigurationConcreteType));

            var typesToProcess = new List <Type>();

            foreach (var assemblyToProcess in assembliesToProcess)
            {
                // add types in assemblies that we haven't processed yet
                if (!AssembliesThatHaveBeenProcessedForRelatedTypes.Contains(assemblyToProcess))
                {
                    var typesToConsiderForThisAssembly = new[] { assemblyToProcess }
                    .GetTypesFromAssemblies()
                    .Where(_ => !IsRestrictedType(_))
                    .ToList();

                    foreach (var typeToConsiderForThisAssembly in typesToConsiderForThisAssembly)
                    {
                        typesToProcess.Add(typeToConsiderForThisAssembly);
                    }

                    AssembliesThatHaveBeenProcessedForRelatedTypes.Add(assemblyToProcess);
                }
            }

            DiscoverAncestorsAndDescendants(typesToProcess);
        }
コード例 #4
0
        private static SerializationConfigurationBase GetOrAddInstance(
            SerializationConfigurationType serializationConfigurationType)
        {
            lock (SyncInstances)
            {
                if (!Instances.ContainsKey(serializationConfigurationType))
                {
                    var instance = serializationConfigurationType.ConcreteSerializationConfigurationDerivativeType.Construct <SerializationConfigurationBase>();

                    var children = instance.DependentSerializationConfigurationTypesWithDefaultsIfApplicable.Distinct().ToList();

                    var descendentTypeToInstanceMap = new Dictionary <SerializationConfigurationType, SerializationConfigurationBase>();

                    foreach (var child in children)
                    {
                        var childInstance = GetOrAddInstance(child);

                        var childDescendantsTypeToInstanceMap = childInstance.DescendantSerializationConfigurationTypeToInstanceMap;

                        // add the dependent's dependents to the dictionary
                        foreach (var childDescendant in childDescendantsTypeToInstanceMap.Keys)
                        {
                            if (!descendentTypeToInstanceMap.ContainsKey(childDescendant))
                            {
                                var childDescendantInstance = childDescendantsTypeToInstanceMap[childDescendant];

                                descendentTypeToInstanceMap.Add(childDescendant, childDescendantInstance);
                            }
                        }

                        // add the dependent to the dictionary
                        if (!descendentTypeToInstanceMap.ContainsKey(child))
                        {
                            descendentTypeToInstanceMap.Add(child, childInstance);
                        }
                    }

                    // initialize with fully resolve dependency tree
                    instance.Initialize(descendentTypeToInstanceMap);

                    Instances.Add(serializationConfigurationType, instance);
                }

                var result = Instances[serializationConfigurationType];

                return(result);
            }
        }