public async Task <DocActionModel> GetActionDocModel(IHeaderDictionary headers, MethodInfo methodInfo) { if (methodInfo == null) { throw new ArgumentNullException(nameof(methodInfo), "Method information not specified."); } DocAction actionDoc = _docModule.GetActionDoc(methodInfo); if (actionDoc == null) { return(await Task.FromResult <DocActionModel>(null)); } var actionDocModel = new DocActionModel(actionDoc); await AddResourceDocs(actionDocModel, actionDoc); Type responseResourceType = ActionExtensions.GetActionResponseResourceType(methodInfo); if (responseResourceType != null) { // Based on the accept type, load the resource metadata which will contain information // about the associated link relations. Add documentation for each resource link. IResourceMeta resourceMeta = _resourceMediaModule.GetRequestedResourceMediaMeta(headers, responseResourceType); AddResourceRelationDocs(actionDocModel, actionDoc, resourceMeta); } return(actionDocModel); }
/// <summary> /// Applies the link metadata defined for one resource type to another. This can be used when there /// are multiple representations for a resource type. This is the case where there is a resource type /// and also different corresponding view-models. When this is the case, often the links associated /// with the base resource type are also to be specified on the associated view-models. This also /// avoids from having to inherit resources and view-models from each other. /// </summary> /// <typeparam name="TFromResource">The type of an already mapped resource.</typeparam> /// <returns>Reference to self for method chaining.</returns> public TResourceMeta ApplyLinkMetaFrom <TFromResource>() where TFromResource : class, IResource { IResourceMeta resourceMeta = GetResourceMeta(typeof(TFromResource)); AddValidLinks(resourceMeta); return((TResourceMeta)this); }
/// <summary> /// Add an item containing metadata for a specific resource type. /// </summary> /// <param name="resourceMeta">The resource metadata configured by derived map.</param> protected void AddResourceMeta(IResourceMeta resourceMeta) { if (resourceMeta == null) { throw new ArgumentNullException(nameof(resourceMeta), "Resource metadata not specified."); } _resourceMeta.Add(resourceMeta); }
protected IResourceMeta GetResourceMeta(Type resourceType) { IResourceMeta resourceMeta = _resourceMap.ResourceMeta .FirstOrDefault(m => m.ResourceType == resourceType); if (resourceMeta == null) { throw new InvalidOperationException( $"Resource Metadata does not exist or has not yet been added for resource type: {resourceType.AssemblyQualifiedName}"); } return(resourceMeta); }
// Creates a new resource mapping for a new resource type based on an existing resource type. // Only the links for which the new resource meets the criteria of the original resource type // are copied. For example of the original link is based on a resource property of FooBarId, // and the resource to which the link is being copied does not have such a property, the link // will not be assigned to the new resource type. private void AddValidLinks(IResourceMeta resourceMeta) { foreach (ActionLink actionLink in resourceMeta.Links) { if (actionLink.CanBeAppliedTo(typeof(TResource))) { ActionLink newResourceLink = actionLink.CreateCopyFor <TResource>(); AddLink(newResourceLink); } } }
/// <summary> /// Adds the resource metadata associated with a specific resource type. /// </summary> /// <param name="resourceMeta">The resource metadata.</param> public void AddResourceMeta(IResourceMeta resourceMeta) { if (resourceMeta == null) { throw new ArgumentNullException(nameof(resourceMeta), "Resource metadata not specified."); } if (_resourceTypeMeta.ContainsKey(resourceMeta.ResourceType)) { throw new InvalidOperationException( $"Resource metadata already specified for resource type: {resourceMeta.ResourceType.FullName}"); } _resourceTypeMeta[resourceMeta.ResourceType] = resourceMeta; }
private void AddResourceRelationDocs(DocActionModel actionDocModel, DocAction actionDoc, IResourceMeta resourceMeta) { DocRelation[] relationDocs = resourceMeta.Links.Select( link => new DocRelation(link) { Description = GetRelationDescription(link, actionDoc, _docModule.GetCommonDefinitions()) }).ToArray(); actionDocModel.Relations = relationDocs; }