public void Initialize(IStateManager stateManager, IReferenceManager referenceManager, ISurrogateManager surrogateManager)
        {
            this.stateManager     = stateManager;
            this.referenceManager = referenceManager;
            this.surrogateManager = surrogateManager;
            var tkey   = typeof(TKey);
            var tvalue = typeof(TValue);

            var tkeyIsValueTypeOrStringOrTypeNotStruct = IsValueTypeOrStringOrTypeNotStruct(tkey);
            var tvalueIsValueTypeOrString = IsValueTypeOrStringOrType(tvalue);

            if (tkeyIsValueTypeOrStringOrTypeNotStruct && tvalueIsValueTypeOrString)
            {
                implementation = new DictCase1 <TKey, TValue>();
                CaseType       = 1;
            }
            else if (tkeyIsValueTypeOrStringOrTypeNotStruct &&
                     (typeof(IStateObject).IsAssignableFrom(tvalue) ||
                      TypeCacheUtils.IsIListOrIDictionary(tvalue))


                     )
            {
                implementation = new DictCase2 <TKey, TValue>(stateManager, referenceManager);
                ((DictCase2 <TKey, TValue>)implementation).SetParent(this);
                CaseType = 2;
            }
            else if (tkeyIsValueTypeOrStringOrTypeNotStruct && typeof(Delegate).IsAssignableFrom(tvalue))
            {
                implementation = new DictCase5 <TKey, TValue>(stateManager, surrogateManager);

                CaseType = 5;
            }
            else if (typeof(IStateObject).IsAssignableFrom(tkey) && tvalueIsValueTypeOrString)
            {
                implementation = new DictCase3 <TKey, TValue>();
                CaseType       = 3;
            }
            else if (typeof(IStateObject).IsAssignableFrom(tkey) &&
                     (typeof(IStateObject).IsAssignableFrom(tvalue) || TypeCacheUtils.IsIListOrIDictionary(tvalue))
                     )
            {
                implementation = new DictCase4 <TKey, TValue>();
                CaseType       = 4;
            }
            else if (tkeyIsValueTypeOrStringOrTypeNotStruct && SurrogatesDirectory.IsSurrogateRegistered(tvalue))
            {
                implementation = new DictCase6 <TKey, TValue>(stateManager, surrogateManager, referenceManager);
                ((DictCase6 <TKey, TValue>)implementation).SetParent(this);
                CaseType = 6;
            }
            else
            {
                throw new NotSupportedException();
            }
        }
            public SerializerMethods(JsonReader reader, Type keyType, Type valueType)
            {
                this.reader    = reader;
                this.keyType   = keyType;
                this.valueType = valueType;

                //First assign delegate depending on keyType
                if (typeof(string) == keyType)
                {
                    ReadKeyMethod = ReadInputAsString;
                }
                else if (typeof(Type) == keyType)
                {
                    ReadKeyMethod = ReadInputAsType;
                }
                else if (typeof(IStateObject).IsAssignableFrom(keyType))
                {
                    ReadKeyMethod = ReadInputAsStateObject;
                }
                else if (keyType.IsEnum)
                {
                    ReadKeyMethod = ReadInputAsEnum;
                }
                else
                {
                    ReadKeyMethod = ReadInputAsOther;
                }

                //Second assign delegate depending on valueType
                if (typeof(string) == valueType)
                {
                    ReadValueMethod = ReadInputAsString;
                }
                else if (typeof(Type) == valueType)
                {
                    ReadValueMethod = ReadInputAsType;
                }
                else if (valueType.IsEnum)
                {
                    ReadValueMethod = ReadInputValueAsEnum;
                }
                else if (typeof(IStateObject).IsAssignableFrom(valueType) ||
                         TypeCacheUtils.IsIListOrIDictionary(valueType) ||
                         typeof(Delegate).IsAssignableFrom(valueType) ||
                         SurrogatesDirectory.IsSurrogateRegistered(valueType))
                {
                    ReadValueMethod = ReadInputAsStateObject;
                }
                else
                {
                    ReadValueMethod = ReadInputValueAsOther;
                }
            }
 /// <summary>
 /// Method to register a surrogate in order to save the State of the method being executed.
 /// </summary>
 /// <param name="codePromiseType"></param>
 /// <param name="target"></param>
 /// <returns></returns>
 internal static void RegisterSurrogateForDisplayClass(Type codePromiseType, object target, string parentSurrogateId = null)
 {
     //Lets register the surrogate only if it's not already registered.
     if (!SurrogatesDirectory.IsSurrogateRegistered(codePromiseType))
     {
         var signature = SurrogatesDirectory.GenerateNewSurrogateFromType(codePromiseType);
         var surrogateForDisplayClass = new SurrogateForDisplayClass(codePromiseType, signature);
         SurrogatesDirectory.RegisterSurrogate(
             signature: signature,
             supportedType: codePromiseType,
             serializeEx: surrogateForDisplayClass.Serialize,
             deserializeEx: surrogateForDisplayClass.Deserialize,
             calculateDependencies: new SurrogateDependencyCalculation[] { surrogateForDisplayClass.CalculateDependencies });
     }
 }
            public SerializerMethods(JsonWriter writer, Type keyType, Type valueType)
            {
                this.writer    = writer;
                this.keyType   = keyType;
                this.valueType = valueType;
                //First assign delegate depending on keyType
                if (typeof(string) == keyType)
                {
                    WriteKeyMethod = WriteKeyGeneric;
                }
                else if (typeof(Type) == keyType)
                {
                    WriteKeyMethod = WriteKeyType;
                }
                else if (typeof(IStateObject).IsAssignableFrom(keyType))
                {
                    WriteKeyMethod = WriteKeyStateObject;
                }
                else
                {
                    WriteKeyMethod = WriteKeyGeneric;
                }

                //Second assign delegate depending on valueType
                if (typeof(string) == valueType)
                {
                    WriteValueMethod = WriteValueGeneric;
                }
                else if (typeof(Type) == valueType)
                {
                    WriteValueMethod = WriteValueType;
                }
                else if (typeof(IStateObject).IsAssignableFrom(valueType) ||
                         TypeCacheUtils.IsIListOrIDictionary(valueType) ||
                         typeof(Delegate).IsAssignableFrom(valueType) ||
                         SurrogatesDirectory.IsSurrogateRegistered(valueType))
                {
                    WriteValueMethod = WriteValueStateObject;
                }
                else
                {
                    WriteValueMethod = WriteValueGeneric;
                }
            }
        public static IList <object> CalculateDependencies(object value, ISurrogateDependenciesContext dependenciesContext)
        {
            var fldArr = GetFieldInfosIncludingBaseClasses(value.GetType(), BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public);
            var res    = new object[fldArr.Count];

            for (int i = 0; i < res.Length; i++)
            {
                var currentField = fldArr[i];
                if (typeof(IStateObject).IsAssignableFrom(currentField.FieldType))
                {
                    res[i] = currentField.GetValue(value);
                }
                else if (currentField.FieldType.IsSerializable && typeof(MulticastDelegate).IsAssignableFrom(currentField.FieldType))
                {
                    //Skip do no support delegate fields
                }
                else if (SurrogatesDirectory.IsSurrogateRegistered(currentField.FieldType))
                {
                    res[i] = currentField.GetValue(value);
                }
            }
            return(res);
        }
Пример #6
0
            static Func <object[], IIocContainerFlags, T> DetermineStrategy()
            {
                var type = typeof(T);

                if (typeof(ILogic).IsAssignableFrom(type))
                {
                    return((object[] parameters, IIocContainerFlags flags) => _current.ResolveNonSinglentonLogic <T>(parameters, flags));
                }
                if (typeof(IStateObject).IsAssignableFrom(type))
                {
                    return((object[] parameters, IIocContainerFlags flags) => _current.ResolveNonSinglentonIStateObject <T>(parameters, flags));
                }
                if (typeof(T).IsGenericType)
                {
                    if (typeof(T).GetGenericTypeDefinition() == typeof(IList <>))
                    {
                        var listType = typeof(VirtualList <>).MakeGenericType(typeof(T).GetGenericArguments());
                        var func     = Expression.Lambda <Func <object> >(Expression.Convert(Expression.New(listType), typeof(object))).Compile();
                        return((object[] parameters, IIocContainerFlags flags) => (T)_current.ResolveList(listType, func, parameters, flags));
                    }
                    if (typeof(T).GetGenericTypeDefinition() == typeof(IDictionary <,>))
                    {
                        var dictionaryType = typeof(ObservableDictionaryEx <,>).MakeGenericType(typeof(T).GetGenericArguments());
                        var func           = Expression.Lambda <Func <object> >(Expression.Convert(Expression.New(dictionaryType), typeof(object))).Compile();
                        return((object[] parameters, IIocContainerFlags flags) => (T)_current.ResolveDictionary(dictionaryType, func, parameters, flags));
                    }
                }
                if (SurrogatesDirectory.IsSurrogateRegistered(typeof(T)))
                {
                    return((object[] parameters, IIocContainerFlags flags) => _current.ResolveSurrogate <T>(parameters));
                }
                if (typeof(T).GetCustomAttributes(typeof(Singleton), false).Length > 0)
                {
                    return((object[] parameters, IIocContainerFlags flags) => _current.ResolveSinglenton <T>(parameters, flags));
                }
                return((object[] parameters, IIocContainerFlags flags) => (T)_current.ResolveReduced(typeof(T), parameters, flags));
            }
        private static void LoadTable(Type type)
        {
            lock (cachePropertiesEx)
            {
                if (cachePropertiesEx.ContainsKey(type))
                {
                    return;
                }



                PropertiesExDictionary properties;
                var ancestorProperties = GetAncestorProperties(type);
                properties = ancestorProperties != null ? new PropertiesExDictionary(ancestorProperties) : new PropertiesExDictionary();

                //Use to asign a IndexParameter field when don't have index parameters for the property
                int numberOfParentProperties = 0;
                if (ALIAS_ENABLED)
                {
                    //Determine how many properties the parent has
                    var baseType = type.BaseType;
                    while (baseType != null)
                    {
                        numberOfParentProperties += baseType.GetProperties(BindingFlags.Public | BindingFlags.Instance).Count();
                        baseType = baseType.BaseType;
                    }
                }
                //short i = 0;
                var aliasIndex = numberOfParentProperties;
                //TODO: should we exclude properties here? like non-virtual or stateobject false?
                var  assemblyAttribute = (StateManagementDefaultValue)type.Assembly.GetCustomAttribute(typeof(StateManagementDefaultValue));
                var  typeName          = type.Name;
                bool flag = false;
                foreach (PropertyInfo prop in type.GetProperties(BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly))
                {
                    var    propName      = prop.Name;
                    string propertyAlias = aliasIndex.ToBase48ToString();
                    aliasIndex++;
                    var typeAttribute = (StateManagementDefaultValue)Attribute.GetCustomAttribute(prop.DeclaringType, typeof(StateManagementDefaultValue), false);
                    var attr          = (StateManagement)prop.GetCustomAttributes(typeof(StateManagement), true).FirstOrDefault();

                    if (attr != null && !attr.RequiresStateManagement())
                    {
                        properties.RemoveProperty(propName);
                        continue;
                    }

                    bool isStrongReference = false;
                    bool isWeakReference   = false;
                    bool onlyHasGetter     = false;
                    bool isAssignableFromIModel;
                    bool isAssignableFromITopLevelStateObject;
                    bool isAssignableFromIViewManager;
                    bool isAssignableFromIIocContainer;
                    bool isAssignableFromILogicWithViewModel_IViewModel;
                    bool isVisibleStateFlag = false;
                    bool hasIndexParameters = false;
                    bool isAssignableFromIDependantViewModel = false;
                    //if (HasNoGetter(prop))
                    //{
                    //    //It will not be added to the list of propertyInfoEx
                    //    continue;
                    //}
                    //else if (HasNoSetter(prop))
                    //{
                    //    //It will not added to the list of propertyInfoEx but we will keep the flag
                    //    if (attr == null)
                    //        attr = new StateManagement(StateManagementValues.ClientOnly);
                    //    onlyHasGetter = true;
                    //}

                    /*if (!prop.CanRead)
                     * {
                     *  attr = new StateManagement(StateManagementValues.None);
                     * }*/
                    //We should exclude ViewManager and Container
                    if ((propName == "ViewManager" && prop.PropertyType == typeof(IViewManager)) ||
                        (propName == "Container" && prop.PropertyType == typeof(IIocContainer)))
                    {
                        continue;
                    }

                    var isStateObject  = typeof(IStateObject).IsAssignableFrom(prop.PropertyType);
                    var propertyType   = prop.PropertyType;
                    var propertyInfoEx = new PropertyInfoEx();
                    propertyInfoEx.OnlyHasGetter = onlyHasGetter;
                    if (ALIAS_ENABLED)
                    {
                        var aliasAttribute = (StateManagementAlias)prop.GetCustomAttributes(typeof(StateManagementAlias), true).FirstOrDefault();
                        if (aliasAttribute != null)
                        {
                            propertyInfoEx.alias = aliasAttribute.Value;
                        }
                        else
                        {
                            propertyInfoEx.alias = propertyAlias;
                        }
                    }
                    propertyInfoEx.prop         = prop;
                    propertyInfoEx.hasSurrogate = SurrogatesDirectory.IsSurrogateRegistered(propertyType);
                    var attrRef = prop.GetCustomAttributes(typeof(Reference), true).FirstOrDefault() as Reference;
                    propertyInfoEx.hasReferenceAttribute = attrRef != null;
                    if (propertyInfoEx.hasReferenceAttribute)
                    {
                        isStrongReference = attrRef.Value == ReferenceTypeValues.Strong;
                        isWeakReference   = attrRef.Value == ReferenceTypeValues.Weak;
                    }
                    isAssignableFromIModel = typeof(IModel).IsAssignableFrom(propertyType);
                    propertyInfoEx.isAssignableFromIDependantStateObject = typeof(IDependentStateObject).IsAssignableFrom(propertyType);
                    isAssignableFromIDependantViewModel  = typeof(IDependentViewModel).IsAssignableFrom(propertyType);
                    isAssignableFromITopLevelStateObject = typeof(ITopLevelStateObject).IsAssignableFrom(propertyType);
                    isAssignableFromIIocContainer        = typeof(IIocContainer).IsAssignableFrom(propertyType);
                    isAssignableFromIViewManager         = typeof(IViewManager).IsAssignableFrom(propertyType);

                    propertyInfoEx.isAnIDictionary = TypeCacheUtils.IsAnIDictionary(propertyType);
                    propertyInfoEx.isAnIList       = TypeCacheUtils.IsAnIList(propertyType);
                    if (prop.Name.Equals("VisibleState", StringComparison.Ordinal) && prop.PropertyType == typeof(VisibleState))
                    {
                        isVisibleStateFlag = true;
                    }
                    StateManagementValues stateManagementAttribute = StateManagementValues.Both;
                    if (attr != null)
                    {
                        stateManagementAttribute = attr.Value;
                    }
                    else if (typeAttribute != null)
                    {
                        if (!propertyInfoEx.isAnIList && !isAssignableFromIDependantViewModel)
                        {
                            stateManagementAttribute = typeAttribute.Value;
                        }
                    }
                    else if (assemblyAttribute != null)
                    {
                        if (!propertyInfoEx.isAnIList && !isAssignableFromIDependantViewModel)
                        {
                            stateManagementAttribute = assemblyAttribute.Value;
                        }
                    }

                    propertyInfoEx.stateManagementAttribute = stateManagementAttribute;
                    var indexParameters = prop.GetIndexParameters();
                    hasIndexParameters = (indexParameters != null) && (indexParameters.Length > 0);
                    //propertyInfoEx.propertyPositionIndex = i;

                    propertyInfoEx.mustIgnoreMemberForClient =
                        StateManagementUtils.MustIgnoreMember(true, prop) /*check the statemanagement attribute*/ ||
                        TypeCacheUtils.IsExcludedProperty(prop) ||
                        propertyInfoEx.hasSurrogate || isAssignableFromIDependantViewModel;

                    // propertyInfoEx.CanRead = prop.CanRead && prop.GetGetMethod(false) != null;
                    //	propertyInfoEx.CanWrite = prop.CanWrite && prop.GetGetMethod(false) != null;

                    //Read JsonNet attributes

                    //propertyInfoEx.jsonPropertyAttribute = Attribute.GetCustomAttribute(prop, typeof(Newtonsoft.Json.Serialization.JsonProperty), false);

                    //propertyInfoEx.defaultValueAttribute = Attribute.GetCustomAttribute(prop, typeof(System.ComponentModel.DefaultValueAttribute), false) as System.

                    //Validate if this is an IList of object
                    bool isASupportedValueTypeForIList = false;
                    if (propertyInfoEx.isAnIList && !propertyInfoEx.isAnIList)
                    {
                        //It could be an IList<object>, but it need to have the statemanagement attribute Generict
                        //var collAtt =
                        //	(GenericCollectionTypeInfo)prop.GetCustomAttributes(typeof(GenericCollectionTypeInfo), true).FirstOrDefault();
                        //if (collAtt != null && collAtt.RuntimeType == typeof(IList<IStateObject>))
                        //{
                        //	propertyInfoEx.isAnIListOfSomethingThatImplementsIStateObject = true;
                        //}
                        //else
                        //{
                        var listItemType = propertyType.GetGenericArguments()[0];
                        isASupportedValueTypeForIList = interceptionDelegates.isASupportedValueTypeForIListDelegate(listItemType);
                        TraceUtil.TraceError("invalid IList<object> possible statemanagement issues");
                        //}
                    }

                    isAssignableFromILogicWithViewModel_IViewModel =
                        typeof(ILogicWithViewModel <IViewModel>).IsAssignableFrom(propertyType);
                    propertyInfoEx.isStateObject             = isStateObject;
                    propertyInfoEx.isNonStateObjectFixedType = propertyType.IsValueType || typeof(string) == propertyType ||
                                                               typeof(Type) == propertyType;
                    propertyInfoEx.isObjectPropertyType = typeof(Object) == propertyType;
                    //We Assign the corresponding getter Action
                    if (isStrongReference || propertyInfoEx.isObjectPropertyType)
                    {
                        propertyInfoEx.ProcessGetter = interceptionDelegates.ProcessGetterStrongReference;
                    }
                    else if (isWeakReference)
                    {
                        propertyInfoEx.ProcessGetter = interceptionDelegates.ProcessGetterWeakReference;
                    }
                    else if (propertyInfoEx.hasSurrogate)
                    {
                        propertyInfoEx.ProcessGetter = interceptionDelegates.ProcessGetterSurrogate;
                    }
                    else if (propertyInfoEx.isAssignableFromIDependantStateObject ||
                             propertyInfoEx.isAnIList ||
                             propertyInfoEx.isAnIDictionary || isASupportedValueTypeForIList)
                    {
                        propertyInfoEx.ProcessGetter = interceptionDelegates.ProcessGetterNonTopLevelIStateObject;
                    }
                    else if (isAssignableFromITopLevelStateObject)
                    {
                        propertyInfoEx.ProcessGetter = interceptionDelegates.ProcessGetterTopLevelIStateObject;
                    }
                    else if (isAssignableFromILogicWithViewModel_IViewModel)
                    {
                        propertyInfoEx.ProcessGetter = interceptionDelegates.ProcessGetterNoAction;
                    }
                    else
                    {
                        propertyInfoEx.ProcessGetter = interceptionDelegates.ProcessGetterNoAction;
                    }

                    //We Assign the corresponding setter Action

                    if (isVisibleStateFlag)
                    {
                        //This is a special process setter for handling property VisibleState of ControlBase or FormBase
                        propertyInfoEx.ProcessSetter = interceptionDelegates.ProcessSetterVisibleState;
                    }
                    else if (propertyInfoEx.isObjectPropertyType)
                    {
                        propertyInfoEx.ProcessSetter = interceptionDelegates.ProcessSetterObjectReference;
                    }
                    else if (propertyInfoEx.hasSurrogate)
                    {
                        propertyInfoEx.ProcessSetter = interceptionDelegates.ProcessSetterSurrogate;
                    }
                    else if (isStrongReference)
                    {
                        propertyInfoEx.ProcessSetter = interceptionDelegates.ProcessSetterStrongReference;
                    }
                    else if (propertyInfoEx.hasReferenceAttribute)
                    {
                        propertyInfoEx.ProcessSetter = interceptionDelegates.ProcessSetterWeakReference;
                    }
                    else if (!propertyInfoEx.hasReferenceAttribute && !propertyInfoEx.hasSurrogate)
                    {
                        if (propertyInfoEx.prop.PropertyType.IsValueType || propertyInfoEx.prop.PropertyType == typeof(string))
                        {
                            propertyInfoEx.ProcessSetter = interceptionDelegates.ProcessSetterSimpleTypes;
                        }
                        else if (isAssignableFromILogicWithViewModel_IViewModel)
                        {
                            propertyInfoEx.ProcessSetter = interceptionDelegates.ProcessSetterSimpleTypes;
                        }
                        else
                        {
                            if (propertyInfoEx.prop.PropertyType.IsClass && !typeof(IStateObject).IsAssignableFrom(propertyInfoEx.prop.PropertyType))
                            {
                                propertyInfoEx.ProcessSetter = interceptionDelegates.ProcessSetterSimpleTypes;
                            }
                            else
                            {
                                propertyInfoEx.ProcessSetter = interceptionDelegates.ProcessSetterMostCases;
                            }
                        }
                    }
                    RegisterProperty(propertyInfoEx, properties, hasIndexParameters);

#if DEBUG
                    if (ViewModelAnalysis)
                    {
                        if (!typeof(IInternalData).IsAssignableFrom(type))
                        {
                            if (propertyType.IsInterface &&
                                //!propertyInfoEx.isAnIListOfSomethingThatImplementsIStateObject &&
                                !isAssignableFromIIocContainer &&
                                !isAssignableFromIViewManager &&
                                !propertyInfoEx.isAssignableFromIDependantStateObject &&
                                !(propertyInfoEx.isAnIList && isASupportedValueTypeForIList) &&
                                !isAssignableFromIModel &&
                                !typeof(IViewModel).IsAssignableFrom(propertyType))
                            {
                                var improperType = type;
                                if (improperType.Assembly.IsDynamic)
                                {
                                    improperType = improperType.BaseType;
                                }
                                Dictionary <string, Type> improperTypeTable;
                                if (!ImproperTypes.TryGetValue(improperType, out improperTypeTable))
                                {
                                    ImproperTypes[improperType] = improperTypeTable = new Dictionary <string, Type>();
                                }
                                improperTypeTable[prop.Name] = propertyType;
                            }
                            else if (propertyType == typeof(object) && !propertyInfoEx.hasReferenceAttribute)
                            {
                                var warningType = type;
                                if (warningType.Assembly.IsDynamic)
                                {
                                    warningType = warningType.BaseType;
                                }
                                Dictionary <string, Type> warningTypeTable;
                                if (!WarningTypes.TryGetValue(warningType, out warningTypeTable))
                                {
                                    WarningTypes[warningType] = warningTypeTable = new Dictionary <string, Type>();
                                }
                                warningTypeTable[prop.Name] = propertyType;
                            }
                        }
                    }
#endif
                }
                ////for loop is faster, but cannot iterate on the dictionary
                //foreach (var item in properties)
                //{
                //    tuple2.Add(item.Key, item.Value.propertyPositionIndex);

                //    bitArrayMappedTable[item.Value.propertyPositionIndex] = item.Value;
                //}
                //cache with position
                properties.PropertiesList = properties.PropertiesList.ToArray();
                cachePropertiesEx.Add(type, properties);
            }
        }
 public bool IsSurrogateRegistered(Type supportedType)
 {
     return(SurrogatesDirectory.IsSurrogateRegistered(supportedType));
 }
Пример #9
0
        /// <summary>
        /// Gets a Reference for an specified value and property.
        /// </summary>
        /// <param name="propEx">The property associated to the value being set.</param>
        /// <param name="parentInstance">The parent instance of the property</param>
        /// <param name="newValueObject">The new value for the property.</param>
        /// <returns></returns>
        private static StateObjectPointerReference GetReference(PropertyInfoEx propEx, IStateObject parentInstance, object newValueObject)
        {
            StateObjectPointerReference reference = null;
            string name        = GetPropertyName(propEx);
            var    relativeUid = UniqueIDGenerator.GetPointerRelativeUniqueID(parentInstance, name);

            AddDependent(parentInstance, UniqueIDGenerator.REFERENCEPrefix + name);
            //Let's try to cast the element to IStateObject
            var newValue = newValueObject as IStateObject;

            //It's an IList, IDisctionary or an IStateObject or the Value is an IStateObject
            if (propEx.isStateObject || propEx.isAnIList || propEx.isAnIDictionary || newValue != null)
            {
                reference = new StateObjectPointerReference();
            }
            //It's a value type or type.
            else if (propEx.isNonStateObjectFixedType)
            {
                reference = new StateObjectPointerReferenceSuperValue();
            }
            //It's declared as an Object.
            else if (propEx.isObjectPropertyType)
            {
                var newValueType = newValueObject.GetType();
                //If the Value is an IStateObject
                if (newValueType.IsValueType || newValueType == typeof(string) || newValueType == typeof(Type))
                {
                    if (TypeCacheUtils.IsAnUserStructType(propEx.prop.PropertyType))
                    {
                        reference = new StateObjectPointerReferenceSuperStruct();
                    }
                    else
                    {
                        reference = new StateObjectPointerReferenceSuperValue();
                    }
                }
                //It's a registered surrogated.
                else if (SurrogatesDirectory.IsSurrogateRegistered(newValueType))
                {
                    reference = new StateObjectPointerReferenceSuperSurrogate();
                }
                else
                {
                    reference = new StateObjectPointerReferenceSerializable();
                }
            }
            else             //Not supported type
            {
                var stackTrace = new StackTrace(3, true);
                throw new InvalidOperationException(
                          "LazyBehaviour::ProcessSetter Property with reference attribute receive a value of unsupported type.\r\n" +
                          "Additional Info: \r\n" +
                          "Value Type: " + propEx.prop.PropertyType.FullName + "\r\n" +
                          "Property Type: " + GetPropertyName(propEx) + "\r\n" +
                          "Error Location: " + stackTrace);
            }
            //If it has the StateManagement attribute set as ServerOnly, then let's respect that.
            if (propEx.stateManagementAttribute == StateManagementValues.ServerOnly)
            {
                StateManager.Current.isServerSideOnly.Add(reference);
            }
            //Let's set the UniqueID to the new reference.
            StateObjectPointer.AssignUniqueIdToPointer(parentInstance, relativeUid, reference);
            //Let's return the pointer of the desired type.
            return(reference);
        }
        /// <summary>
        /// Reads the JSON and converts to the real object.
        /// </summary>
        public static object ReadObject(JsonReader reader, Type expectedType = null, ISurrogateContext context = null)
        {
            object      newInstance              = null;
            Array       newInstanceAsArray       = null;
            IList       newInstanceAsIList       = null;
            IDictionary newInstanceAsIDictionary = null;
            Type        elementType              = null;
            JObject     jobj = JObject.Load(reader);

            var  assemblyQualifiedType = jobj["__type"].Value <string>();
            Type targetType            = SurrogatesDirectory.ContractedStringToType(assemblyQualifiedType);

            var isArray = jobj["__isArray"] != null ? jobj["__isArray"].Value <bool>() : false;

            if (isArray)
            {
                var length          = jobj["__arrayLength"].Value <int>();
                var elementTypeName = jobj["__elementType"].Value <string>();
                elementType = SurrogatesDirectory.ContractedStringToType(elementTypeName);
                newInstance = newInstanceAsArray = Array.CreateInstance(elementType, length);
            }
            else
            {
                newInstance = Activator.CreateInstance(targetType);
            }

            foreach (JProperty prop in jobj.Properties())
            {
                MemberInfo reflectedMember = null;
                object     adapterValue    = null;

                if (prop.Name == "__type")
                {
                    continue;
                }
                if (prop.Name == "__isArray")
                {
                    continue;
                }
                if (prop.Name == "__arrayLength")
                {
                    continue;
                }
                if (prop.Name == "__elementType")
                {
                    continue;
                }
                if (prop.Name == "__dict")
                {
                    newInstanceAsIDictionary = newInstance as IDictionary;
                    var keys   = prop.Value["_keys"].Value <JArray>();
                    var values = prop.Value["_values"].Value <JArray>();
                    var index  = 0;
                    foreach (var key in keys)
                    {
                        newInstanceAsIDictionary.Add(key, values[index++]);
                    }
                }
                else if (prop.Name == "__arr")
                {
                    var values = prop.Value as IEnumerable;
                    var index  = 0;
                    if (!isArray)
                    {
                        newInstanceAsIList = (IList)newInstance;
                    }
                    foreach (var item in values)
                    {
                        var itemAsJValue = item as JValue;
                        if (isArray)
                        {
                            if (itemAsJValue != null)
                            {
                                if (itemAsJValue.Type == JTokenType.Object)
                                {
                                    newInstanceAsArray.SetValue(ReadObject(itemAsJValue.CreateReader(), null, context), index);
                                }
                                else
                                {
                                    newInstanceAsArray.SetValue(Convert.ChangeType(itemAsJValue.Value, elementType), index);
                                }
                            }
                            else
                            {
                                newInstanceAsArray.SetValue(ReadObject((item as JObject).CreateReader(), null, context), index);
                            }
                        }
                        else
                        {
                            if (itemAsJValue != null)
                            {
                                if (itemAsJValue.Type == JTokenType.Object)
                                {
                                    newInstanceAsIList.Add(ReadObject(itemAsJValue.CreateReader(), null, context));
                                }
                                else
                                {
                                    newInstanceAsIList.Add(itemAsJValue.Value);
                                }
                            }
                            else
                            {
                                newInstanceAsIList.Add(ReadObject((item as JObject).CreateReader(), null, context));
                            }
                        }
                        index++;
                    }
                }
                else
                {
                    //Check that is always ONE member.

                    reflectedMember = GetFieldInfoIncludingBaseClasses(targetType, prop.Name, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
                    var reflectedField = reflectedMember as FieldInfo;
                    try
                    {
                        if (reflectedField != null)
                        {
                            if (reflectedField.FieldType.IsValueType || reflectedField.FieldType.Name.Equals("String"))
                            {
                                adapterValue = Convert.ChangeType(prop.Value, reflectedField.FieldType);
                                reflectedField.SetValue(newInstance, adapterValue);
                            }
                            else
                            {
                                var currentField = reflectedField;
                                if (typeof(IStateObject).IsAssignableFrom(currentField.FieldType))
                                {
                                    var uniqueID = prop.Value.Value <string>();
                                    if (!String.IsNullOrWhiteSpace(uniqueID))
                                    {
                                        reflectedField.SetValue(newInstance, context.RestoreStateObject(uniqueID));
                                    }
                                }
                                else if (currentField.FieldType.IsSerializable && typeof(MulticastDelegate).IsAssignableFrom(currentField.FieldType))
                                {
                                    //Skip do no support delegate fields
                                }
                                else if (SurrogatesDirectory.IsSurrogateRegistered(currentField.FieldType))
                                {
                                    var uniqueID = prop.Value.Value <string>();
                                    if (!String.IsNullOrWhiteSpace(uniqueID))
                                    {
                                        reflectedField.SetValue(newInstance, context.RestoreSurrogateValue(uniqueID));
                                    }
                                }
                                else
                                {
                                    adapterValue = (prop.Value.ToString() == String.Empty) ? null : ReadObject(prop.Value.CreateReader(), reflectedField.FieldType, context);
                                    reflectedField.SetValue(newInstance, adapterValue);
                                }
                            }
                        }
                    }
                    catch
                    {
                        throw new InvalidOperationException("Error While deserialing object.");
                    }
                }
            }
            return(newInstance);
        }
        /// <summary>
        /// Writes the given object and returns the JSON string
        /// </summary>
        public static void WriteObject(JsonWriter writer, object value, ISurrogateContext context)
        {
            writer.WriteStartObject();
            Type valueType = value.GetType();

            writer.WritePropertyName("__type");
            string assemblyQualifiedName = SurrogatesDirectory.TypeToContractedString(valueType);

            writer.WriteValue(assemblyQualifiedName);
            if (value is System.Collections.IDictionary)
            {
                SerializeDictionary(writer, value, context);
            }
            else if (value is System.Collections.IEnumerable)
            {
                SerializeEnumerable(writer, value, valueType, context);
            }
            else
            {
                var fldArr = GetFieldInfosIncludingBaseClasses(valueType, BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public);

                for (var i = 0; i < fldArr.Count; i++)
                {
                    var propEx       = fldArr[i];
                    var propValue    = propEx.GetValue(value);
                    var currentField = fldArr[i];
                    if (typeof(IStateObject).IsAssignableFrom(currentField.FieldType))
                    {
                        writer.WritePropertyName(propEx.Name);
                        writer.WriteValue(((IStateObject)propValue).UniqueID);
                    }
                    else if (currentField.FieldType.IsSerializable && typeof(MulticastDelegate).IsAssignableFrom(currentField.FieldType))
                    {
                        //Skip do no support delegate fields
                    }
                    else if (SurrogatesDirectory.IsSurrogateRegistered(currentField.FieldType))
                    {
                        if (propValue != null)
                        {
                            var surr = context.GetStateObjectSurrogate(propValue, generateIfNotFound: false);
                            if (surr == null)
                            {
                                throw new InvalidOperationException();
                            }

                            writer.WritePropertyName(propEx.Name);
                            writer.WriteValue(((IStateObject)surr).UniqueID);
                        }
                        else
                        {
                            writer.WritePropertyName(propEx.Name);
                            writer.WriteValue(String.Empty);
                        }
                    }
                    else
                    {
                        //Lets check if that value is not a dependency.
                        //if (dependencies != null && IsObjectInDependencies(dependencies, propValue))
                        //    continue;
                        writer.WritePropertyName(propEx.Name);
                        WriteValueAux(writer, propValue, propEx.FieldType, context);
                    }
                }
            }
            writer.WriteEndObject();
        }
        private static void SerializeFields(StateManager stateManager, object instance, ref IStateObject viewModel, BinaryWriter writer, Type logicObjectType, IList <FieldInfo> fieldList, string fieldPrefix = "")
        {
            var formatter = new BinaryFormatter();

            foreach (var field in fieldList)
            {
#if DEBUG
                Trace.WriteLine(string.Format("Serializing promise field {0}.{1}", fieldPrefix, field.Name));
#endif
                var objValue = field.GetValue(instance);
                if (objValue == null)
                {
                    continue;                   //We do not need to save null fields
                }
                ///The delegate can be an instance method. We are looking to determine if there is a reference to the "this instance"
                if (IsThisTheThisField(stateManager, instance, field, logicObjectType, objValue, writer, fieldPrefix, ref viewModel))
                {
                    continue;
                }
                if (field.Name.Contains("locals"))
                {
                    var parentSurrogate = stateManager.surrogateManager.GetSurrogateFor(instance, generateIfNotFound: false);
                    if (parentSurrogate == null)
                    {
                        throw new InvalidOperationException("A parent surrogate is needed");
                    }
                    var localsSurrogate = stateManager.surrogateManager.GetSurrogateFor(objValue, generateIfNotFound: false);
                    if (localsSurrogate == null) //There was not a previous surrogate!! Ok we need a lastminute one
                    {
                        throw new Exception("Invalid condition. Surrogate dependency should have been reported previously");
                        //RegisterSurrogateForDisplayClass(field.FieldType, objValue,parentSurrogate.UniqueID);

                        //localsSurrogate = stateManager.surrogateManager.GetSurrogateFor(objValue, generateIfNotFound: true, parentSurrogate: parentSurrogate.UniqueID);
                        //stateManager.surrogateManager.AddSurrogateReference(localsSurrogate, parentSurrogate.UniqueID);
                    }
                    writer.Write(field.Name);
                    writer.Write(localsSurrogate.UniqueID);
                    continue;
                }
                //If we have a value we need to serialize
                //We will write the fieldName + Value
                bool isSerializable = false;
                if (objValue is IStateObject || IsInterfaceThatMightBeAnStateObject(objValue))
                {
                    //For IStateObject only the UniqueID is needed for the other we would use the ISerialize
                    var value = (IStateObject)objValue;
                    //If this field is not the this then we are goint to save its value
                    writer.Write(fieldPrefix + field.Name);
                    var orphanHolder = stateManager.AdoptionInformation.GetOrphanHolder(instance, value, field.Name);
                    if (orphanHolder == null)
                    {
                        writer.Write(value.UniqueID);
                    }
                    else
                    {
                        writer.Write(orphanHolder.UniqueID);
                    }
                }
                else if (objValue is ILogicWithViewModel <IStateObject> )
                {
                    var value = (ILogicWithViewModel <IStateObject>)objValue;
                    Debug.Assert(value.ViewModel != null);
                    writer.Write(fieldPrefix + field.Name);
                    writer.Write(value.ViewModel.UniqueID);
                }
                else if ((isSerializable = (field.FieldType.IsSerializable || objValue.GetType().IsSerializable)) && objValue is MulticastDelegate)
                {
                    SerializeDelegate(stateManager, instance, writer, fieldPrefix, field, objValue);
                }
                else if (SurrogatesDirectory.IsSurrogateRegistered(field.FieldType))
                {
                    var surrogate = stateManager.surrogateManager.GetSurrogateFor(objValue, generateIfNotFound: true);
                    if (surrogate == null)
                    {
                        // Something is wrong here, throw an exception
                        throw new InvalidOperationException("Error getting the surrogate for field " + field.Name + " with type " + field.FieldType.FullName + " inside object of type " + instance.GetType().FullName);
                    }
                    var parentSurrogate = stateManager.surrogateManager.GetSurrogateFor(instance, generateIfNotFound: false);
                    stateManager.surrogateManager.AddSurrogateReference(surrogate, parentSurrogate);
                    writer.Write(field.Name);
                    writer.Write(surrogate.UniqueID);
                }
                else if (isSerializable)
                {
                    writer.Write(fieldPrefix + field.Name);
                    formatter.Serialize(writer.BaseStream, objValue);
                }
                else
                {
                    throw new NotSupportedException("Error serializing field " + field.Name + " with type " + field.FieldType.FullName + " inside object of type " + instance.GetType().FullName);
                }
            }
        }
        internal static void CalculateDependencies(object instance, Type codePromiseType, ref IList <object> dependencies)
        {
            var fieldList = codePromiseType.Fields(BindingFlags.Public | BindingFlags.Instance);

            if (fieldList.Count == 0)
            {
                return;
            }
            if (dependencies == null)
            {
                dependencies = new List <object>(fieldList.Count);
            }
            var logicObjectType = codePromiseType.DeclaringType;

            foreach (var field in fieldList)
            {
                //TODO skip value type. However some delegates return IsValueType true
#if DEBUG
                Trace.WriteLine(string.Format("Checking promise dependency field {0}", field.Name));
#endif
                var objValue = field.GetValue(instance);
                if (objValue == null)
                {
                    continue;                   //We do not need to save null fields
                }
                if (CheckTheThisField(instance, field, logicObjectType, objValue, ref dependencies))
                {
                    continue;
                }
                if (field.Name.Contains("locals"))
                {
                    //Here we know that this is a display class

                    dependencies.Add(objValue);
                    RegisterSurrogateForDisplayClass(field.FieldType, objValue);
                    continue;
                }
                var isISerializable = false;
                //If we have a value we need to serialize
                //We will write the fieldName + Value
                if (objValue is IStateObject)
                {
                    dependencies.Add(objValue);
                }
                else if
                ((isISerializable = (field.FieldType.IsSerializable || objValue.GetType().IsSerializable)) &&
                 objValue is MulticastDelegate)
                {
                    var delegateObj = ((MulticastDelegate)objValue);
                    if (delegateObj.Target != null && delegateObj.Target != instance)
                    {
                        dependencies.Add(delegateObj);
                    }
                }
                else if (objValue is ILogicWithViewModel <IStateObject> )
                {
                    //var value = (ILogicWithViewModel<IStateObject>)objValue;
                }
                else if (SurrogatesDirectory.IsSurrogateRegistered(field.FieldType))
                {
                    dependencies.Add(objValue);
                }
                else if (field.FieldType.IsSerializable || objValue.GetType().IsSerializable)
                {
                    //    if (typeof(MulticastDelegate).IsAssignableFrom(field.FieldType))
                    //    {
                    //        var delegateObj = ((MulticastDelegate)objValue);
                    //        var target = delegateObj.Target;
                    //        if (target == null)
                    //        {
                    //        }
                    //        else
                    //        {
                    //            //Is the target the display class?
                    //            if (Object.ReferenceEquals(instance, target))
                    //            {
                    //            }
                    //            else if (target is IStateObject)
                    //            {
                    //                dependencies.Add(target);
                    //            }
                    //            else
                    //                throw new NotImplementedException("No serialization for this delegates has been implemented yet!");
                    //        }
                    //    }
                    //    else if (field.FieldType.IsClass)
                    //    {

                    //    }
                }
                //else if (TypeCacheUtils.IsSpecialClass (objValue.GetType()))
                //{
                //    CalculateDependencies(objValue, objValue.GetType(), ref dependencies);
                //}
                else
                {
                    throw new NotSupportedException("Error serializing field " + field.Name + " with type " + field.FieldType.FullName + " inside object of type " + instance.GetType().FullName);
                }
            }
        }
        internal static void DeserializeStateForDelegate(BinaryReader reader, Type delegateClassType, object instance, ref string fieldName, string prefix = null)
        {
            var formatter = new BinaryFormatter();
            var fieldList = delegateClassType.Fields(BindingFlags.Public | BindingFlags.Instance);

            foreach (var field in fieldList)
            {
                if (fieldName == null)
                {
                    if (reader.BaseStream.Position == reader.BaseStream.Length)
                    {/*No more data*/
                        return;
                    }
                    fieldName = reader.ReadString();
                    if (prefix != null)
                    {
                        if (fieldName.StartsWith(prefix, StringComparison.Ordinal))
                        {
                            fieldName = fieldName.Substring(prefix.Length);
                        }
                    }

                    TraceUtil.WriteLine(string.Format("Setting value for field {0}", fieldName));
                }
                //Skip until find matching field
                if (!fieldName.Equals(field.Name, StringComparison.Ordinal))
                {
                    continue;
                }

                if (field.Name.Contains("<>") && field.Name.Contains("locals"))
                {
                    //Is it in locals??
                    //Check if still goes here.
                    var surrogateUID    = reader.ReadString();
                    var localsSurrogate = (StateObjectSurrogate)StateManager.Current.GetObject(surrogateUID);
                    var localsInstance  = localsSurrogate.Value;
                    field.SetValue(instance, localsInstance);
                    fieldName = null;
                    continue;
                }
                //Is not locals.mmm ok is it an StateObject
                if (typeof(IStateObject).IsAssignableFrom(field.FieldType) ||
                    (field.FieldType.IsGenericType &&
                     (typeof(IList <>).IsAssignableFrom(field.FieldType.GetGenericTypeDefinition()) ||
                      typeof(IDictionary <,>).IsAssignableFrom(field.FieldType.GetGenericTypeDefinition()))
                    ))
                {
                    var uid = reader.ReadString();
                    if (!String.IsNullOrWhiteSpace(uid))
                    {
                        var fieldValue = StateManager.Current.GetObject(uid);
                        var surrogate  = fieldValue as StateObjectSurrogate;
                        if (surrogate != null)
                        {
                            fieldValue = surrogate.Value as IStateObject;
                        }
                        field.SetValue(instance, fieldValue);
                    }
                    fieldName = null;
                }
                else if (typeof(ILogicWithViewModel <IStateObject>).IsAssignableFrom(field.FieldType))
                {
                    fieldName = null;
                    var uid = reader.ReadString();
                    var vm  = StateManager.Current.GetObject(uid);
                    if (vm != null)
                    {
                        Type logicType = field.FieldType;
                        if (logicType.IsInterface)
                        {
                            var logicAttr = vm.GetType().GetCustomAttribute(typeof(UpgradeHelpers.Helpers.LogicAttribute)) as UpgradeHelpers.Helpers.LogicAttribute;
                            if (logicAttr == null)
                            {
                                throw new InvalidOperationException("The logic type for the viewmodel could not be determined. Please decorate the ViewModel class type with the Logic Attribute. for example [Logic(Type = typeof(LogicClass)]");
                            }
                            logicType = logicAttr.Type;
                        }

                        var form = IocContainerImplWithUnity.Current.Resolve(logicType, null, IIocContainerFlags.NoView | IIocContainerFlags.RecoveredFromStorage) as ILogicView <IViewModel>;
                        form.SetPropertyValue("ViewModel", vm);
                        field.SetValue(instance, form);
                    }
                    else
                    {
                        throw new InvalidOperationException(string.Format("The ViewModel for field {0} could not be restored ", field.Name));
                    }
                }
                else
                {
                    if (field.FieldType.IsSerializable && typeof(MulticastDelegate).IsAssignableFrom(field.FieldType))
                    {
                        RestoreDelegateField(reader, instance, field);
                    }
                    else if (SurrogatesDirectory.IsSurrogateRegistered(field.FieldType))
                    {
                        var uid = reader.ReadString();
                        if (!String.IsNullOrWhiteSpace(uid))
                        {
                            StateObjectSurrogate surrogate = StateManager.Current.surrogateManager.GetObject(uid);
                            field.SetValue(instance, surrogate.Value);
                        }
                    }
                    else if (field.FieldType.IsSerializable)
                    {
                        var fieldValue = formatter.Deserialize(reader.BaseStream);
                        field.SetValue(instance, fieldValue);
                    }
                    fieldName = null;
                }
            }
        }
Пример #15
0
        public object Resolve(Type t, object[] parameters = null, IIocContainerFlags flags = IIocContainerFlags.None)
        {
            var    typeofT      = t;
            object newInstance  = null;
            var    stateManager = StateManager.Current;

            if (SurrogatesDirectory.IsSurrogateRegistered(typeofT))
            {
                //Surrogates are created as top level objects
                //however reference tracking is important because surrogates with no references
                //are not persisted
                if (parameters == null || parameters.Length == 0)
                {
                    //We must create a new instance, instance creation mechanism must be located from
                    //the surrogates directory
                    newInstance = SurrogatesDirectory.CreateInstanceFor(typeofT);
                }
                else
                {
                    newInstance = parameters[0];
                }
                var surrogate = stateManager.surrogateManager.GetSurrogateFor(newInstance, generateIfNotFound: true);
                return(newInstance);
            }
            try
            {
                var isRecoveredFromStorage = (flags & IIocContainerFlags.RecoveredFromStorage) == IIocContainerFlags.RecoveredFromStorage;
                if (!isRecoveredFromStorage)
                {
                    if (t.GetCustomAttributes(typeof(Singleton), false).Length > 0)
                    {
                        flags       = flags | IIocContainerFlags.IsSinglenton;
                        newInstance = StateManager.Current.GetObject(UniqueIDGenerator.GetSinglentonUniqueId(t));
                        if ((flags & IIocContainerFlags.SinglentonNonReturnIfExisting) == IIocContainerFlags.SinglentonNonReturnIfExisting)
                        {
                            if (newInstance != null)
                            {
                                return(null);
                            }
                        }
                        if ((flags & IIocContainerFlags.SinglentonReturnIfExisting) == IIocContainerFlags.SinglentonReturnIfExisting)
                        {
                            if (newInstance != null)
                            {
                                return(newInstance);
                            }
                        }
                        //At this point the object was recovered from storage and it the RecoveredFromStorageFlags must
                        //added to avoid unnecessary further processing of this object
                        isRecoveredFromStorage = (newInstance != null);
                    }
                }
                newInstance = newInstance ?? ResolveUnPrepared(t, isRecoveredFromStorage);
                if (newInstance is IViewManager)
                {
                    //Nothing to do
                }
                else if (newInstance is ILogic)
                {
                    InitializeObject(stateManager, this, (ILogic)newInstance, parameters, t, isRecoveredFromStorage, flags);
                }
                else if (newInstance is IStateObject)
                {
                    if (!isRecoveredFromStorage)
                    {
                        InitializeObject(stateManager, this, (IStateObject)newInstance, parameters, t, flags);
                    }
                }
                else
                {
                    if (!alreadyAssertedTypes.Contains(t))
                    {
                        alreadyAssertedTypes.Add(t);
                        Trace.TraceError("IocContainerImplWithUInity::Resolve WARNING: Type to resolved [" + t.FullName + "] is not an IStateObject, so there is no tracking or serialization available for that object");
                    }
                }
            }
            finally
            {
                if (newInstance is IStateObject)
                {
                    stateManager.RemoveIDInResolution(((IStateObject)newInstance).UniqueID);
                }
            }
            return(newInstance);
        }
 /// <summary>
 /// Indicates if this is a valid type combination
 /// </summary>
 /// <param name="t"></param>
 /// <returns></returns>
 internal bool IsSupportedKeyValuePairDictionary(Type t)
 {
     if (t.IsGenericType)
     {
         var types      = t.GetGenericArguments();
         var key        = types[0];
         var value      = types[1];
         var validKey   = (IsValueTypeOrStringOrTypeNotStruct(key) || typeof(IStateObject).IsAssignableFrom(key));
         var validValue = (IsValueTypeOrStringOrType(value) || typeof(IStateObject).IsAssignableFrom(value) || SurrogatesDirectory.IsSurrogateRegistered(value));
         if (!validValue && value.IsGenericType)
         {
             var genericValueType = value.GetGenericTypeDefinition();
             if (genericValueType == typeof(IList <>))
             {
                 validValue = TypeCacheUtils.IsSupportedGenericTypeForList(value);
             }
             else if (genericValueType == typeof(IDictionary <,>))
             {
                 validValue = IsSupportedKeyValuePairDictionary(value);
             }
         }
         return(validKey && validValue);
     }
     throw new ArgumentException("This method should only be called for generic types");
 }