/// <summary> /// Registers the default type handlers. /// </summary> /// private static Dictionary <Guid, ThingTypeHandler> RegisterDefaultTypeHandlers( out Dictionary <string, ThingTypeHandler> typeHandlersByClassName) { Dictionary <Guid, ThingTypeHandler> typeHandlers = new Dictionary <Guid, ThingTypeHandler>(); typeHandlersByClassName = new Dictionary <string, ThingTypeHandler>( StringComparer.OrdinalIgnoreCase); foreach (DefaultTypeHandler typeHandler in s_defaultTypeHandlers) { ThingTypeHandler handler = new ThingTypeHandler(typeHandler.TypeId, typeHandler.Type); typeHandlers.Add( typeHandler.TypeId, handler); typeHandlersByClassName.Add( typeHandler.TypeName, handler); } return(typeHandlers); }
/// <summary> /// Registers a deserializer for item type-specific data. /// </summary> /// /// <param name="typeId"> /// The unique identifier for the item type-specific data as defined /// by the HealthVault service. /// </param> /// /// <param name="itemTypeClass"> /// The class that implements the item type-specific data. It must /// be public, derive from <see cref="ThingBase"/>, and /// have a default constructor. /// </param> /// /// <param name="overwriteExisting"> /// <b>true</b> to register the new deserializer even if the type /// already has a deserializer registered; <b>false</b> to throw an /// exception because a deserializer is already registered. /// </param> /// /// <exception cref="ArgumentException"> /// The <paramref name="typeId"/> parameter is <see cref="System.Guid.Empty"/> or /// the <paramref name="itemTypeClass"/> parameter does not derive from /// <see cref="ThingBase"/>. /// </exception> /// /// <exception cref="ArgumentNullException"> /// The <paramref name="itemTypeClass"/> parameter is <b>null</b>. /// </exception> /// /// <exception cref="TypeHandlerAlreadyRegisteredException"> /// The <paramref name="typeId"/> parameter already has a handler /// registered and <paramref name="overwriteExisting"/> is <b>false</b>. /// </exception> /// public static void RegisterTypeHandler( Guid typeId, Type itemTypeClass, bool overwriteExisting = false) { if (typeId == Guid.Empty) { throw new ArgumentException(Resources.TypeIdGuidEmpty, nameof(typeId)); } Validator.ThrowIfArgumentNull(itemTypeClass, nameof(itemTypeClass), Resources.ThingTypeClassNull); if (!itemTypeClass.GetTypeInfo().IsSubclassOf(typeof(ThingBase))) { throw new ArgumentException(Resources.TypeClassNotThing, nameof(itemTypeClass)); } if (TypeHandlers.ContainsKey(typeId) && !overwriteExisting) { throw new TypeHandlerAlreadyRegisteredException(Resources.TypeHandlerAlreadyRegistered); } TypeHandlers[typeId] = new ThingTypeHandler(typeId, itemTypeClass); s_typeHandlersByClassName[itemTypeClass.Name] = TypeHandlers[typeId]; }
/// <summary> /// Gets the <see cref="Type"/> instance of the class that is registered to /// handle this type id. /// </summary> /// <remarks> /// This method looks up the type id in the list of types that the SDK understands how /// to process. If new types were added to the HealthVault service since this SDK was /// released, this method will not return them. /// /// To retrieve information about the types from the HealthVault service, /// use the <see cref="GetHealthRecordItemTypeDefinitionAsync(IConnectionInternal)"/> method. /// </remarks> /// <param name="typeId">The ID of the associated type</param> /// <returns>The typeId.</returns> public static Type GetRegisteredTypeForTypeId(Guid typeId) { if (TypeHandlers.ContainsKey(typeId)) { ThingTypeHandler itemTypeHandler = TypeHandlers[typeId]; return(itemTypeHandler.ItemTypeClass); } return(null); }
internal static ThingBase DeserializeItem(XPathNavigator thingNav) { ThingBase result; Guid typeId = GetTypeId(thingNav); ThingTypeHandler handler = null; if (typeId == s_applicationSpecificId) { // Handle application specific health item records by checking for handlers // for the application ID and subtype tag. If the handler doesn't exist // the default handler will be picked up below. AppDataKey appDataKey = GetAppDataKey(thingNav); if (appDataKey != null) { if (s_appSpecificHandlers.ContainsKey(appDataKey.AppId)) { if (s_appSpecificHandlers[appDataKey.AppId].ContainsKey(appDataKey.SubtypeTag)) { handler = s_appSpecificHandlers[appDataKey.AppId][appDataKey.SubtypeTag]; } } } } if (handler == null && TypeHandlers.ContainsKey(typeId)) { handler = TypeHandlers[typeId]; } if (handler != null) { result = (ThingBase)Activator.CreateInstance(handler.ItemTypeClass); } else { result = new ThingBase(typeId); } result.ParseXml(thingNav, thingNav.OuterXml); return(result); }
/// <summary> /// Registers a deserializer for item extension data. /// </summary> /// /// <remarks> /// Extension data is available to all applications, and since there is no registration /// method for the extensionSource identifiers, collisions between applications are possible. /// /// Applications should be written to be tolerant of the presence of extension data using the /// same extensionSource but a different schema. It is also recommended that extensionSource be /// specified the same way .NET namespaces are specified, prefixing the extensionSource with the /// company name. /// </remarks> /// /// <param name="extensionSource"> /// The unique identifier for the source of the item extension. /// </param> /// /// <param name="itemExtensionClass"> /// The class that implements the item extension. It must /// be public, derive from <see cref="ThingExtension"/>, /// and have a default constructor. /// </param> /// /// <param name="overwriteExisting"> /// <b>true</b> to register the new deserializer even if the type /// already has a deserializer registered; <b>false</b> to throw an /// exception because a deserializer is already registered. /// </param> /// /// <exception cref="ArgumentException"> /// The <paramref name="extensionSource"/> parameter is <b>null</b> or empty or /// the <paramref name="itemExtensionClass"/> parameter does not derive from /// <see cref="ThingExtension"/>. /// </exception> /// /// <exception cref="ArgumentNullException"> /// The <paramref name="itemExtensionClass"/> parameter is <b>null</b>. /// </exception> /// /// <exception cref="TypeHandlerAlreadyRegisteredException"> /// The <paramref name="extensionSource"/> already has a handler /// registered and <paramref name="overwriteExisting"/> is <b>false</b>. /// </exception> /// public static void RegisterExtensionHandler( string extensionSource, Type itemExtensionClass, bool overwriteExisting) { Validator.ThrowIfStringNullOrEmpty(extensionSource, "extensionSource"); Validator.ThrowIfArgumentNull(itemExtensionClass, nameof(itemExtensionClass), Resources.ItemExtensionClassNull); if (s_extensionHandlers.ContainsKey(extensionSource) && !overwriteExisting) { throw new TypeHandlerAlreadyRegisteredException(Resources.ExtensionHandlerAlreadyRegistered); } s_extensionHandlers[extensionSource] = new ThingTypeHandler(itemExtensionClass); }
/// <summary> /// Deserializes the response XML for extensions into a /// <see cref="ThingExtension"/> or derived type based on the registered /// extension handler. /// </summary> /// /// <param name="extensionNav"> /// The XML representation of the extension data. /// </param> /// /// <returns> /// The <see cref="ThingExtension"/> or derived class instance /// representing the data in the XML. /// </returns> /// /// <exception cref="System.Reflection.TargetInvocationException"> /// If the constructor of the type being created throws an /// exception. The inner exception is the exception thrown by the /// constructor. /// </exception> /// /// <exception cref="MissingMethodException"> /// The default constructor of the type being created is not public. /// If you registered the extension handler, be sure that the type you /// registered for the extension type class has a public default /// constructor. /// </exception> /// internal static ThingExtension DeserializeExtension( XPathNavigator extensionNav) { ThingExtension result; string source = extensionNav.GetAttribute("source", string.Empty); if (s_extensionHandlers.ContainsKey(source)) { ThingTypeHandler handler = s_extensionHandlers[source]; result = (ThingExtension)Activator.CreateInstance( handler.ItemTypeClass); } else { result = new ThingExtension(source); } result.ParseXml(extensionNav); return(result); }
/// <summary> /// Registers a class as the handler for the application specific health record /// item type with the specific application ID and subtype tag. /// </summary> /// /// <param name="applicationId"> /// The application identifier for the application specific data that the /// specified type will handle. /// </param> /// /// <param name="subtypeTag"> /// The subtype tag for the application specific data that the specified type /// will handle. /// </param> /// /// <param name="applicationSpecificHandlerClass"> /// The .NET type that handles parsing of the application specific data for /// the specified application ID and subtype tag. /// </param> /// /// <param name="overwriteExisting"> /// If true and an entry exist for the specified <paramref name="applicationId"/> /// and <paramref name="subtypeTag"/> it will be replaced. /// </param> /// /// <exception cref="ArgumentException"> /// If <paramref name="applicationId"/> or <paramref name="subtypeTag"/> is /// <b>null</b> or empty, or if <paramref name="applicationSpecificHandlerClass"/> /// does not derive from ApplicationSpecific. /// </exception> /// /// <exception cref="ArgumentNullException"> /// If <paramref name="applicationSpecificHandlerClass"/> is <b>null</b>. /// </exception> /// /// <exception cref="TypeHandlerAlreadyRegisteredException"> /// If a type is already registered to handle the application specific data /// for the specified <paramref name="applicationId"/> and /// <paramref name="subtypeTag"/> and <paramref name="overwriteExisting"/> is false. /// </exception> /// public static void RegisterApplicationSpecificHandler( string applicationId, string subtypeTag, Type applicationSpecificHandlerClass, bool overwriteExisting) { Validator.ThrowIfStringNullOrEmpty(applicationId, "applicationId"); Validator.ThrowIfStringNullOrEmpty(subtypeTag, "subtypeTag"); Validator.ThrowIfArgumentNull(applicationSpecificHandlerClass, nameof(applicationSpecificHandlerClass), Resources.AppDataHandlerClassMandatory); if (applicationSpecificHandlerClass.GetTypeInfo().BaseType.Name != nameof(ApplicationSpecific)) { throw new ArgumentException(Resources.AppDataHandlerNotApplicationSpecific, nameof(applicationSpecificHandlerClass)); } Dictionary <string, ThingTypeHandler> handlerDictionary; if (s_appSpecificHandlers.ContainsKey(applicationId)) { handlerDictionary = s_appSpecificHandlers[applicationId]; if (handlerDictionary.ContainsKey(subtypeTag) && !overwriteExisting) { throw new TypeHandlerAlreadyRegisteredException(Resources.AppDataHandlerAlreadyRegistered); } } else { handlerDictionary = new Dictionary <string, ThingTypeHandler>(); s_appSpecificHandlers.Add(applicationId, handlerDictionary); } ThingTypeHandler handler = new ThingTypeHandler(applicationSpecificHandlerClass); handlerDictionary[subtypeTag] = handler; }