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); }
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)); }
/// <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; } } }
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"); }