├── swaggerexample.png
├── src
├── Controllerless.WebApi.Description
│ ├── packages.config
│ ├── Internal
│ │ ├── Requires.cs
│ │ ├── ControllerlessControllerDescriptor.cs
│ │ ├── CollectionExtensions.cs
│ │ └── ControllerlessParameterDescriptor.cs
│ ├── ITypeDescriptionProvider.cs
│ ├── CompositeApiExplorer.cs
│ ├── CompositeTypeDescriptionProvider.cs
│ ├── Properties
│ │ └── AssemblyInfo.cs
│ ├── ControllerlessActionDescriptor.cs
│ ├── XmlDocumentationTypeDescriptionProvider.cs
│ ├── Controllerless.WebApi.Description.csproj
│ └── ControllerlessApiExplorer.cs
├── Controllerless.WebApi
│ ├── Properties
│ │ └── AssemblyInfo.cs
│ └── Controllerless.WebApi.csproj
└── Controllerless.WebApi.Description.sln
├── LICENSE
├── .gitignore
└── README.md
/swaggerexample.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dotnetjunkie/controllerless/HEAD/swaggerexample.png
--------------------------------------------------------------------------------
/src/Controllerless.WebApi.Description/packages.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/src/Controllerless.WebApi.Description/Internal/Requires.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace SolidServices.Controllerless.WebApi.Description
4 | {
5 | internal static class Requires
6 | {
7 | public static void IsNotNull(object instance, string paramName)
8 | {
9 | if (object.ReferenceEquals(instance, null))
10 | {
11 | throw new ArgumentNullException(paramName);
12 | }
13 | }
14 | }
15 | }
--------------------------------------------------------------------------------
/src/Controllerless.WebApi.Description/Internal/ControllerlessControllerDescriptor.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.ObjectModel;
2 | using System.Web.Http.Controllers;
3 |
4 | namespace SolidServices.Controllerless.WebApi.Description
5 | {
6 | internal sealed class ControllerlessControllerDescriptor : HttpControllerDescriptor
7 | {
8 | // note you might provide some asp.net attributes here
9 | public override Collection GetCustomAttributes() => new Collection();
10 | }
11 | }
--------------------------------------------------------------------------------
/src/Controllerless.WebApi.Description/Internal/CollectionExtensions.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 |
7 | namespace SolidServices.Controllerless.WebApi.Description
8 | {
9 | internal static class CollectionExtensions
10 | {
11 | public static void AddRange(this ICollection collection, IEnumerable range)
12 | {
13 | foreach (var item in range) collection.Add(item);
14 | }
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/src/Controllerless.WebApi.Description/ITypeDescriptionProvider.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace SolidServices.Controllerless.WebApi.Description
4 | {
5 | ///
6 | /// Provides descriptions for requested types.
7 | ///
8 | public interface ITypeDescriptionProvider
9 | {
10 | /// Gets the type's description or null when there is no description for the given type.
11 | /// The type.
12 | /// The description of the requested type or null.
13 | string GetDescription(Type type);
14 | }
15 | }
--------------------------------------------------------------------------------
/src/Controllerless.WebApi.Description/Internal/ControllerlessParameterDescriptor.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Web.Http.Controllers;
3 | using System.Web.Http.Description;
4 |
5 | namespace SolidServices.Controllerless.WebApi.Description
6 | {
7 | internal sealed class ControllerlessParameterDescriptor : HttpParameterDescriptor
8 | {
9 | private readonly string parameterName;
10 | private readonly Type parameterType;
11 |
12 | // HttpActionDescriptor actionDescriptor,
13 | internal ControllerlessParameterDescriptor(string parameterName, Type parameterType)
14 | {
15 | this.parameterName = ToCamelCase(parameterName);
16 | this.parameterType = parameterType;
17 | }
18 |
19 | public override string ParameterName => this.parameterName;
20 | public override Type ParameterType => this.parameterType;
21 |
22 | private static string ToCamelCase(string name) => name.Substring(0, 1).ToLower() + name.Substring(1);
23 | }
24 | }
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2016 Steven
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/src/Controllerless.WebApi.Description/CompositeApiExplorer.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.ObjectModel;
3 | using System.Linq;
4 | using System.Web.Http.Description;
5 |
6 | namespace SolidServices.Controllerless.WebApi.Description
7 | {
8 | ///
9 | /// Wraps multiple instances and combines them into one collection of api descriptions.
10 | /// The results will be cached.
11 | ///
12 | public sealed class CompositeApiExplorer : IApiExplorer
13 | {
14 | private readonly Lazy> descriptions;
15 |
16 | /// Constructs a new instance of .
17 | ///
18 | public CompositeApiExplorer(params IApiExplorer[] apiExplorers)
19 | {
20 | Requires.IsNotNull(apiExplorers, nameof(apiExplorers));
21 |
22 | this.descriptions = new Lazy>(() =>
23 | new Collection(apiExplorers.SelectMany(x => x.ApiDescriptions).ToList()));
24 | }
25 |
26 | /// Gets the API descriptions.
27 | public Collection ApiDescriptions => this.descriptions.Value;
28 | }
29 | }
--------------------------------------------------------------------------------
/src/Controllerless.WebApi/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using System.Runtime.CompilerServices;
3 | using System.Runtime.InteropServices;
4 |
5 | // General Information about an assembly is controlled through the following
6 | // set of attributes. Change these attribute values to modify the information
7 | // associated with an assembly.
8 | [assembly: AssemblyTitle("Controllerless.WebApi")]
9 | [assembly: AssemblyDescription("")]
10 | [assembly: AssemblyConfiguration("")]
11 | [assembly: AssemblyCompany("")]
12 | [assembly: AssemblyProduct("Controllerless.WebApi")]
13 | [assembly: AssemblyCopyright("Copyright © 2016")]
14 | [assembly: AssemblyTrademark("")]
15 | [assembly: AssemblyCulture("")]
16 |
17 | // Setting ComVisible to false makes the types in this assembly not visible
18 | // to COM components. If you need to access a type in this assembly from
19 | // COM, set the ComVisible attribute to true on that type.
20 | [assembly: ComVisible(false)]
21 |
22 | // The following GUID is for the ID of the typelib if this project is exposed to COM
23 | [assembly: Guid("8af38c39-4bb8-4d0d-9b3f-b6f1c19a8d08")]
24 |
25 | // Version information for an assembly consists of the following four values:
26 | //
27 | // Major Version
28 | // Minor Version
29 | // Build Number
30 | // Revision
31 | //
32 | // You can specify all the values or you can default the Build and Revision Numbers
33 | // by using the '*' as shown below:
34 | // [assembly: AssemblyVersion("1.0.*")]
35 | [assembly: AssemblyVersion("1.0.0.0")]
36 | [assembly: AssemblyFileVersion("1.0.0.0")]
37 |
--------------------------------------------------------------------------------
/src/Controllerless.WebApi.Description/CompositeTypeDescriptionProvider.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace SolidServices.Controllerless.WebApi.Description
4 | {
5 | ///
6 | /// Wraps a set of instances and the first found description of a requested type.
7 | ///
8 | public sealed class CompositeTypeDescriptionProvider : ITypeDescriptionProvider
9 | {
10 | private readonly ITypeDescriptionProvider[] providers;
11 |
12 | ///
13 | /// Constructs a new instance of .
14 | ///
15 | ///
16 | public CompositeTypeDescriptionProvider(params ITypeDescriptionProvider[] providers)
17 | {
18 | Requires.IsNotNull(providers, nameof(providers));
19 | this.providers = providers;
20 | }
21 |
22 | /// Gets the type's description or null when there is no description for the given type.
23 | /// The type.
24 | /// The description of the requested type or null.
25 | public string GetDescription(Type type)
26 | {
27 | foreach (var provider in this.providers)
28 | {
29 | string description = provider.GetDescription(type);
30 |
31 | if (!string.IsNullOrEmpty(description))
32 | {
33 | return description;
34 | }
35 | }
36 |
37 | return null;
38 | }
39 | }
40 | }
--------------------------------------------------------------------------------
/src/Controllerless.WebApi.Description.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | # Visual Studio 14
4 | VisualStudioVersion = 14.0.25420.1
5 | MinimumVisualStudioVersion = 10.0.40219.1
6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Controllerless.WebApi.Description", "Controllerless.WebApi.Description\Controllerless.WebApi.Description.csproj", "{7325A177-DD50-4AAC-A899-59C281E532C9}"
7 | EndProject
8 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Controllerless.WebApi", "Controllerless.WebApi\Controllerless.WebApi.csproj", "{8AF38C39-4BB8-4D0D-9B3F-B6F1C19A8D08}"
9 | EndProject
10 | Global
11 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
12 | Debug|Any CPU = Debug|Any CPU
13 | Release|Any CPU = Release|Any CPU
14 | EndGlobalSection
15 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
16 | {7325A177-DD50-4AAC-A899-59C281E532C9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
17 | {7325A177-DD50-4AAC-A899-59C281E532C9}.Debug|Any CPU.Build.0 = Debug|Any CPU
18 | {7325A177-DD50-4AAC-A899-59C281E532C9}.Release|Any CPU.ActiveCfg = Release|Any CPU
19 | {7325A177-DD50-4AAC-A899-59C281E532C9}.Release|Any CPU.Build.0 = Release|Any CPU
20 | {8AF38C39-4BB8-4D0D-9B3F-B6F1C19A8D08}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
21 | {8AF38C39-4BB8-4D0D-9B3F-B6F1C19A8D08}.Debug|Any CPU.Build.0 = Debug|Any CPU
22 | {8AF38C39-4BB8-4D0D-9B3F-B6F1C19A8D08}.Release|Any CPU.ActiveCfg = Release|Any CPU
23 | {8AF38C39-4BB8-4D0D-9B3F-B6F1C19A8D08}.Release|Any CPU.Build.0 = Release|Any CPU
24 | EndGlobalSection
25 | GlobalSection(SolutionProperties) = preSolution
26 | HideSolutionNode = FALSE
27 | EndGlobalSection
28 | EndGlobal
29 |
--------------------------------------------------------------------------------
/src/Controllerless.WebApi.Description/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Resources;
2 | using System.Reflection;
3 | using System.Runtime.CompilerServices;
4 | using System.Runtime.InteropServices;
5 |
6 | // General Information about an assembly is controlled through the following
7 | // set of attributes. Change these attribute values to modify the information
8 | // associated with an assembly.
9 | [assembly: AssemblyTitle("SolidServices.Controllerless.WebApi.Description")]
10 | [assembly: AssemblyDescription("Custom ApiExplorer for genrating API documentation for message based apis.")]
11 | [assembly: AssemblyConfiguration("")]
12 | [assembly: AssemblyCompany("dotnetjunkie")]
13 | [assembly: AssemblyProduct("Controllerless.WebApi.Description")]
14 | [assembly: AssemblyCopyright("Copyright © 2016 dotnetjunkie")]
15 | [assembly: AssemblyTrademark("")]
16 | [assembly: AssemblyCulture("")]
17 |
18 | // Setting ComVisible to false makes the types in this assembly not visible
19 | // to COM components. If you need to access a type in this assembly from
20 | // COM, set the ComVisible attribute to true on that type.
21 | [assembly: ComVisible(false)]
22 |
23 | // The following GUID is for the ID of the typelib if this project is exposed to COM
24 | [assembly: Guid("7325a177-dd50-4aac-a899-59c281e532c9")]
25 |
26 | // Version information for an assembly consists of the following four values:
27 | //
28 | // Major Version
29 | // Minor Version
30 | // Build Number
31 | // Revision
32 | //
33 | // You can specify all the values or you can default the Build and Revision Numbers
34 | // by using the '*' as shown below:
35 | // [assembly: AssemblyVersion("1.0.*")]
36 | [assembly: AssemblyVersion("0.1.2.0")]
37 | [assembly: AssemblyFileVersion("0.1.2.0")]
38 | [assembly: NeutralResourcesLanguage("en-US")]
39 |
40 |
--------------------------------------------------------------------------------
/src/Controllerless.WebApi/Controllerless.WebApi.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Debug
6 | AnyCPU
7 | {8AF38C39-4BB8-4D0D-9B3F-B6F1C19A8D08}
8 | Library
9 | Properties
10 | Controllerless.WebApi
11 | Controllerless.WebApi
12 | v4.5
13 | 512
14 |
15 |
16 | true
17 | full
18 | false
19 | bin\Debug\
20 | DEBUG;TRACE
21 | prompt
22 | 4
23 |
24 |
25 | pdbonly
26 | true
27 | bin\Release\
28 | TRACE
29 | prompt
30 | 4
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
53 |
--------------------------------------------------------------------------------
/src/Controllerless.WebApi.Description/ControllerlessActionDescriptor.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Collections.ObjectModel;
4 | using System.Linq;
5 | using System.Threading;
6 | using System.Threading.Tasks;
7 | using System.Web.Http.Controllers;
8 | using System.Web.Http.Description;
9 |
10 | namespace SolidServices.Controllerless.WebApi.Description
11 | {
12 | ///
13 | /// An used by Controllerless for constructing APIs for Actions.
14 | ///
15 | public sealed class ControllerlessActionDescriptor : HttpActionDescriptor
16 | {
17 | private readonly Collection parameters;
18 |
19 | internal ControllerlessActionDescriptor(ApiDescription description, Type messageType, string actionName,
20 | Type returnType, IEnumerable parameters)
21 | {
22 | this.ApiDescription = description;
23 | this.MessageType = messageType;
24 | this.ActionName = actionName;
25 | this.ReturnType = returnType;
26 | this.parameters = new Collection(parameters.ToList());
27 | this.parameters.ToList().ForEach(p => p.ActionDescriptor = this);
28 | }
29 |
30 | /// Gets the parent .
31 | public ApiDescription ApiDescription { get; }
32 |
33 | /// The type of the message that this action processes.
34 | public Type MessageType { get; }
35 |
36 | /// The name of the action.
37 | public override string ActionName { get; }
38 |
39 | /// Gets the return type of the descriptor..
40 | public override Type ReturnType { get; }
41 |
42 | /// Retrieves the parameters for the action descriptor.
43 | /// The parameters for the action descriptor.
44 | public override Collection GetParameters() => this.parameters;
45 |
46 | ///
47 | /// Gets the custom attributes for the .
48 | ///
49 | /// The type of attribute to search for.
50 | /// true to search this action's inheritance chain to find the attributes; otherwise, false.
51 | /// The collection of custom attributes applied to this action.
52 | public override Collection GetCustomAttributes(bool inherit) =>
53 | new Collection(this.MessageType.GetCustomAttributes(typeof(T), inherit).OfType().ToArray());
54 |
55 | /// Throws an exception.
56 | ///
57 | ///
58 | ///
59 | ///
60 | public override Task