Ejemplo n.º 1
0
        void GenerateFor(TypeMetaData metaData, string property, IPropertyValidator validator)
        {
            var validatorType = validator.GetType();
            var types         = new List <Type>();

            types.Add(validatorType);
            types.AddRange(validatorType.GetTypeInfo().GetInterfaces());
            foreach (var type in types)
            {
                if (_generatorsByType.ContainsKey(type))
                {
                    var propertyName = property.ToCamelCase();
                    var rule         = _generatorsByType[type].GeneratorFrom(property, validator);
                    var ruleName     = rule.GetType().Name.ToCamelCase();
                    metaData[propertyName][ruleName] = rule;
                }
            }
        }
        /// <summary>
        /// Initializes a new instance of the <see cref="DesignTimeTypeDescriptor"/> class.
        /// </summary>
        /// <param name="objectType">Type of the object.</param>
        /// <param name="instance">The instance.</param>
        public EditableTypeDescriptor(Type objectType)
        {
            Type wrapperObjectType = objectType;
            Type wrappedObjectType = objectType;
            Type baseType          = wrapperObjectType.BaseType;

            while (baseType != null && baseType != typeof(object))
            {
                if (baseType.Name == typeof(EditableAdapter <>).Name &&
                    baseType.GetGenericArguments().Length > 0)
                {
                    wrappedObjectType = baseType.GetGenericArguments()[0];
                    break;
                }
                baseType = baseType.BaseType;
            }
            _context = TypeMetaDataRepository.GetFor(wrapperObjectType, wrappedObjectType);
        }
Ejemplo n.º 3
0
        /// <summary>
        /// Initializes the created object after its construction.
        /// </summary>
        /// <param name="obj">The object to initialize.</param>
        /// <param name="typeMetaData">Metadata about object to initialize</param>
        private void InitializeAfterConstruction(object obj, TypeMetaData typeMetaData)
        {
            if (obj == null)
            {
                return;
            }

            string objectType = ObjectToStringHelper.ToTypeString(obj);

            Log.Debug("Initializing type '{0}' after construction", objectType);

            // TODO: Consider to cache for performance
            var dependencyResolverManager = DependencyResolverManager.Default;
            var dependencyResolver        = _serviceLocator.ResolveType <IDependencyResolver>();

            dependencyResolverManager.RegisterDependencyResolverForInstance(obj, dependencyResolver);

            Log.Debug("Injecting properties into type '{0}' after construction", objectType);

            var type = obj.GetType();

            foreach (var injectedProperty in typeMetaData.GetInjectedProperties())
            {
                var propertyInfo    = injectedProperty.Key;
                var injectAttribute = injectedProperty.Value;

                try
                {
                    var dependency = _serviceLocator.ResolveType(injectAttribute.Type, injectAttribute.Tag);
                    propertyInfo.SetValue(obj, dependency, null);
                }
                catch (Exception ex)
                {
                    throw Log.ErrorAndCreateException <InvalidOperationException>(ex, "Failed to set property '{0}.{1}' during property dependency injection", type.Name, propertyInfo.Name);
                }
            }

            var objAsINeedCustomInitialization = obj as INeedCustomInitialization;

            if (objAsINeedCustomInitialization != null)
            {
                objAsINeedCustomInitialization.Initialize();
            }
        }
Ejemplo n.º 4
0
        /// <summary>
        /// Gets the constructors metadata.
        /// </summary>
        /// <param name="type">The type.</param>
        /// <returns>The <see cref="TypeMetaData"/>.</returns>
        private TypeMetaData GetTypeMetaData(Type type)
        {
            return(_typeConstructorsMetadataLock.PerformUpgradableRead(() =>
            {
                if (_typeConstructorsMetadata.TryGetValue(type, out var result))
                {
                    return result;
                }

                result = new TypeMetaData(type);

                _typeConstructorsMetadataLock.PerformWrite(() =>
                {
                    _typeConstructorsMetadata.Add(type, result);
                });

                return result;
            }));
        }
        public void TestMetaDataSerialization()
        {
            var metaData = new TypeMetaData();

            metaData.StoreFieldNumber("blah/", "myName", "someField", 2);

            var serializer = ObjectBuilder.GetSerializer();

            var result = serializer.Serialize(metaData, AppModeType);

            Assert.IsTrue(result.Data.Length > 0, "Meta data was not successfully serialized. The resultant byte count was zero.");

            var deserialized = serializer.Deserialize <TypeMetaData>(result.Data, AppModeType);

            Assert.IsNotNull(deserialized, "Deserialization was not succesfull, the resultant object was null.");

            int?fieldNumber;
            var success = deserialized.GetFieldNumber("blah/", "myName", "someField", out fieldNumber);

            Assert.IsTrue(success, "The expected field number was not found in the deserialized data. MetaData deserialization failed.");

            Assert.AreEqual(2, fieldNumber.Value, "The expected field number was not found in the deserialized data. MetaData deserialization failed.");
        }
        void GenerateForChildValidator(TypeMetaData metaData, Type[] genericArguments, IGrouping <string, IPropertyValidator> member, IPropertyValidator validator, bool isModelRule, string currentKey)
        {
            var isConcept = false;

            if (genericArguments.Length == 1)
            {
                // TODO: This is probably needed because of a bug in FluentValidation.
                //       At least it seems like that. It seems there is some static cached state.
                //       It works fine in isolated tests - but running the whole battery
                //       makes this fail if we take out the "Value" name forcing
                var memberKey = member.Key;
                if (memberKey == string.Empty)
                {
                    memberKey = "Value";
                }

                var type = isModelRule ? genericArguments[0] : GetPropertyInfo(genericArguments[0], memberKey).PropertyType;
                isConcept = type.IsConcept();
            }
            var propertyValidatorContext = new PropertyValidatorContext(new ValidationContext(null), null, null);
            var childValidator           = (validator as ChildValidatorAdaptor).GetValidator(propertyValidatorContext);

            GenerateForValidator(childValidator, metaData, currentKey, isConcept, isModelRule);
        }
Ejemplo n.º 7
0
 private NetworkObject CreateNetworkObject(NetworkObjectList objectList, TypeMetaData metaData, in ObjectHandle objectHandle)
Ejemplo n.º 8
0
 void ISchemaTaintedFormatter.OnSchemaChanged(TypeMetaData meta) => ActivateSchema(meta.CurrentSchema);
Ejemplo n.º 9
0
 internal SerializationResult(byte[] data, TypeMetaData metaData)
 {
     Data = data;
     MetaData = metaData;
 }
Ejemplo n.º 10
0
        IFormatter GetSpecificFormatter(Type type, TypeMetaData meta)
        {
            // 1.) Cache
            if (meta.SpecificFormatter != null)
            {
                return(meta.SpecificFormatter);
            }

            // Sanity checks
            if (type.IsAbstract || type.IsInterface || type.ContainsGenericParameters)
            {
                throw new InvalidOperationException("You cannot get a formatter for abstract, interface, and open generic types because they are not ");
            }


            // 2.) TypeConfig - Custom Formatter, Custom Resolver
            if (meta.TypeConfig.CustomFormatter != null)
            {
                meta.SpecificFormatter = meta.TypeConfig.CustomFormatter;
                FormatterHelper.ThrowOnMismatch(meta.SpecificFormatter, type);
                InjectDependencies(meta.SpecificFormatter);
                return(meta.SpecificFormatter);
            }
            if (meta.TypeConfig.CustomResolver != null)
            {
                var formatter = meta.TypeConfig.CustomResolver(this, type);
                meta.SpecificFormatter = formatter ?? throw new InvalidOperationException($"The custom formatter-resolver registered for Type '{type.FullName}' has returned 'null'.");
                FormatterHelper.ThrowOnMismatch(meta.SpecificFormatter, type);
                InjectDependencies(meta.SpecificFormatter);
                return(meta.SpecificFormatter);
            }


            // 3.) User
            for (int i = 0; i < _userResolvers.Length; i++)
            {
                var formatter = _userResolvers[i](this, type);
                if (formatter != null)
                {
                    meta.SpecificFormatter = formatter;
                    FormatterHelper.ThrowOnMismatch(meta.SpecificFormatter, type);
                    InjectDependencies(formatter);
                    return(formatter);
                }
            }


            // 4.) Depending on the VersionTolerance we use different formatters
            if (Config.VersionTolerance.Mode != VersionToleranceMode.Disabled)
            {
                if (!meta.IsFrameworkType)
                {
                    // Create SchemaFormatter, it will automatically adjust itself to the schema when it's read
                    var formatterType   = typeof(SchemaDynamicFormatter <>).MakeGenericType(type);
                    var schemaFormatter = (IFormatter)Activator.CreateInstance(formatterType, args: new object[] { this, meta.PrimarySchema });

                    meta.SpecificFormatter = schemaFormatter;
                    return(schemaFormatter);
                }
            }


            // 5.) Built-in
            for (int i = 0; i < _resolvers.Count; i++)
            {
                var formatter = _resolvers[i].GetFormatter(type);
                if (formatter != null)
                {
                    meta.SpecificFormatter = formatter;
                    InjectDependencies(formatter);
                    return(formatter);
                }
            }

            // 6.) Dynamic
            {
                var formatter = _dynamicResolver.GetFormatter(type);
                if (formatter != null)
                {
                    meta.SpecificFormatter = formatter;
                    InjectDependencies(formatter);
                    return(formatter);
                }
            }

            throw new NotSupportedException($"Ceras could not find any IFormatter<T> for the type '{type.FullName}'. Maybe exclude that field/prop from serializaion or write a custom formatter for it.");
        }
Ejemplo n.º 11
0
        /// <summary>
        /// Tries to create the service with the specified constructor using the specified parameters.
        /// <para />
        /// This method will not throw an exception when the invocation fails.
        /// </summary>
        /// <param name="typeToConstruct">Type of the service.</param>
        /// <param name="constructor">The constructor info.</param>
        /// <param name="tag">The preferred tag when resolving dependencies.</param>
        /// <param name="parameters">The parameters to pass into the constructor.</param>
        /// <param name="checkConstructor">if set to <c>true</c>, check whether the constructor can be used before using it.</param>
        /// <param name="hasMoreConstructorsLeft">if set to <c>true</c>, more constructors are left so don't throw exceptions.</param>
        /// <param name="typeMetaData">Metadata about type beiing constructed.</param>
        /// <returns>The instantiated service or <c>null</c> if the instantiation fails.</returns>
        /// <remarks>Note that this method does not require an implementation of
        /// <see cref="TypeRequestPath" /> because this already has the parameter values
        /// and thus cannot lead to invalid circular dependencies.</remarks>
        private object TryCreateToConstruct(Type typeToConstruct, ConstructorInfo constructor, object tag, object[] parameters,
                                            bool checkConstructor, bool hasMoreConstructorsLeft, TypeMetaData typeMetaData)
        {
            // Check if this constructor is even possible
            if (checkConstructor)
            {
                if (!CanConstructorBeUsed(constructor, tag, true, parameters))
                {
                    return(null);
                }
            }

            try
            {
                var finalParameters = new List <object>(parameters);
                var ctorParameters  = constructor.GetParameters();
                for (int i = parameters.Length; i < ctorParameters.Length; i++)
                {
                    object ctorParameterValue;

                    if (tag != null && _serviceLocator.IsTypeRegistered(ctorParameters[i].ParameterType, tag))
                    {
                        // Use preferred tag
                        ctorParameterValue = _serviceLocator.ResolveType(ctorParameters[i].ParameterType, tag);
                    }
                    else
                    {
                        // No tag or fallback to default without tag
                        ctorParameterValue = _serviceLocator.ResolveType(ctorParameters[i].ParameterType);
                    }

                    finalParameters.Add(ctorParameterValue);
                }

                var finalParametersArray = finalParameters.ToArray();

                Log.Debug("Calling constructor.Invoke with the right parameters");

                var instance = constructor.Invoke(finalParametersArray);

                InitializeAfterConstruction(instance, typeMetaData);

                return(instance);
            }
#if NET || NETSTANDARD
            catch (MissingMethodException)
            {
                // Ignore, we accept this
            }
#endif
            catch (TargetParameterCountException)
            {
                // Ignore, we accept this
            }
            catch (CircularDependencyException)
            {
                // Only handle CircularDependencyExceptions we throw ourselves because we support generic types such as
                // Dictionary<TKey, TValue> which has a constructor with IDictionary<TKey, TValue>
                if (!hasMoreConstructorsLeft)
                //if (string.Equals(TypeRequestPathName, ex.TypePath.Name, StringComparison.Ordinal))
                {
                    throw;
                }
            }
            catch (Exception ex)
            {
                // Real exceptions bubble up, otherwise return null
                Log.Error(ex, "Failed to instantiate type '{0}', but this was an unexpected error", typeToConstruct.FullName);
                throw;
            }

            // Some loging like .GetSignature are expensive
            var logDebug = LogManager.LogInfo.IsDebugEnabled && !LogManager.LogInfo.IgnoreCatelLogging;
            if (logDebug)
            {
                Log.Debug("Failed to create instance using dependency injection for type '{0}' using constructor '{1}'",
                          typeToConstruct.FullName, constructor.GetSignature());
            }

            return(null);
        }
Ejemplo n.º 12
0
 //Factory function for networked entities
 public INetworkable EntityFactory(TypeMetaData metaData, in ObjectHandle handle)
Ejemplo n.º 13
0
 private static string ConvertToJson(TypeMetaData metaData)
 {
     return(JsonSerializer.ConvertToJson(metaData));
 }
Ejemplo n.º 14
0
        /// <summary>
        /// Tries to create the service with the specified constructor using the specified parameters.
        /// <para />
        /// This method will not throw an exception when the invocation fails.
        /// </summary>
        /// <param name="typeToConstruct">Type of the service.</param>
        /// <param name="constructor">The constructor info.</param>
        /// <param name="tag">The preferred tag when resolving dependencies.</param>
        /// <param name="parameters">The parameters to pass into the constructor.</param>
        /// <param name="checkConstructor">if set to <c>true</c>, check whether the constructor can be used before using it.</param>
        /// <param name="hasMoreConstructorsLeft">if set to <c>true</c>, more constructors are left so don't throw exceptions.</param>
        /// <param name="typeMetaData">Metadata about type beiing constructed.</param>
        /// <returns>The instantiated service or <c>null</c> if the instantiation fails.</returns>
        /// <remarks>Note that this method does not require an implementation of
        /// <see cref="TypeRequestPath" /> because this already has the parameter values
        /// and thus cannot lead to invalid circular dependencies.</remarks>
        private object TryCreateToConstruct(Type typeToConstruct, ConstructorInfo constructor, object tag, object[] parameters,
                                            bool checkConstructor, bool hasMoreConstructorsLeft, TypeMetaData typeMetaData)
        {
            // Check if this constructor is even possible
            if (checkConstructor)
            {
                if (!CanConstructorBeUsed(constructor, tag, true, parameters))
                {
                    return(null);
                }
            }

            try
            {
                var finalParameters = new List <object>(parameters);
                var ctorParameters  = constructor.GetParameters();
                for (var i = parameters.Length; i < ctorParameters.Length; i++)
                {
                    object ctorParameterValue = null;

                    var parameterTypeToResolve = ctorParameters[i].ParameterType;
                    if (!typeof(string).IsAssignableFromEx(parameterTypeToResolve) && typeof(IEnumerable).IsAssignableFromEx(parameterTypeToResolve))
                    {
                        var collectionElementType = parameterTypeToResolve.GetCollectionElementType();
                        if (collectionElementType != null && _serviceLocator.IsTypeRegisteredWithOrWithoutTag(collectionElementType))
                        {
                            var ctorParameterValueLocal = _serviceLocator.ResolveTypes(collectionElementType).Cast(collectionElementType);

                            if (parameterTypeToResolve.IsArray)
                            {
                                ctorParameterValueLocal = ctorParameterValueLocal.ToSystemArray(collectionElementType);
                            }
                            else if (typeof(IReadOnlyList <>).MakeGenericType(collectionElementType).IsAssignableFromEx(parameterTypeToResolve) || typeof(IReadOnlyCollection <>).MakeGenericType(collectionElementType).IsAssignableFromEx(parameterTypeToResolve))
                            {
                                ctorParameterValueLocal = ctorParameterValueLocal.AsReadOnly(collectionElementType);
                            }
                            else if (typeof(IList <>).MakeGenericType(collectionElementType).IsAssignableFromEx(parameterTypeToResolve) || typeof(ICollection <>).MakeGenericType(collectionElementType).IsAssignableFromEx(parameterTypeToResolve))
                            {
                                ctorParameterValueLocal = ctorParameterValueLocal.ToList(collectionElementType);
                            }

                            ctorParameterValue = ctorParameterValueLocal;
                        }
                    }

                    if (ctorParameterValue is null)
                    {
                        if (!(tag is null) && _serviceLocator.IsTypeRegistered(parameterTypeToResolve, tag))
                        {
                            // Use preferred tag
                            ctorParameterValue = _serviceLocator.ResolveType(parameterTypeToResolve, tag);
                        }
                        else
                        {
                            // No tag or fallback to default without tag
                            ctorParameterValue = _serviceLocator.ResolveType(parameterTypeToResolve);
                        }
                    }


                    finalParameters.Add(ctorParameterValue);
                }

                var finalParametersArray = finalParameters.ToArray();

                //Log.Debug("Calling constructor.Invoke with the right parameters");

                var instance = constructor.Invoke(finalParametersArray);

                InitializeAfterConstruction(instance, typeMetaData);

                return(instance);
            }
Ejemplo n.º 15
0
 public AssemblyFormatterGenerator(CerasSerializer ceras, Type type)
 {
     _ceras = ceras;
     _type  = type;
     _meta  = _ceras.GetTypeMetaData(_type);
 }
Ejemplo n.º 16
0
 /// <summary>
 /// Initializes a new instance of the <see cref="EditableAdapter&lt;TWrappedObject&gt;"/> class.
 /// </summary>
 /// <param name="current">The object being wrapped.</param>
 public EditableAdapter(TWrappedObject current)
 {
     _changedProperties = new Dictionary <PropertyInfo, object>();
     _current           = current;
     _metaData          = TypeMetaDataRepository.GetFor(this.GetType(), typeof(TWrappedObject));
 }
 internal SerializationResult(byte[] data, TypeMetaData metaData)
 {
     Data     = data;
     MetaData = metaData;
 }
Ejemplo n.º 18
0
 public Member(MemberInfo info, TypeMetaData metaData, ITypeConverter typeConverter, in BitConverterOptions converterOptions, int?changeNotificationIndex)