Skip to content

Commit

Permalink
Added JsonSerializerSettingsTransformationMethod, DocumentProcessors …
Browse files Browse the repository at this point in the history
…and OperationProcessors settings (cmd line)
  • Loading branch information
RicoSuter committed Oct 6, 2017
1 parent 41ea209 commit 0aad9f1
Show file tree
Hide file tree
Showing 16 changed files with 141 additions and 38 deletions.
38 changes: 38 additions & 0 deletions src/NSwag.AssemblyLoader/AssemblyLoader.cs
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,44 @@ protected void RegisterReferencePaths(IEnumerable<string> referencePaths)
return null;
};
}

protected T CreateInstance<T>(string typeName)
{
try
{
var split = typeName.Split(':');
if (split.Length > 1)
{
var assemblyName = split[0].Trim();
typeName = split[1].Trim();

#if FullNet
var assembly = AppDomain.CurrentDomain.Load(new AssemblyName(assemblyName));
return (T)Activator.CreateInstance(assembly.GetType(typeName, true));
#else
var assembly = Context.LoadFromAssemblyName(new AssemblyName(assemblyName));
return (T)Activator.CreateInstance(assembly.GetType(typeName, true));
#endif
}

#if FullNet
foreach (var assembly in AppDomain.CurrentDomain.GetAssemblies())
{
var type = assembly.GetType(typeName, false, true);
if (type != null)
return (T)Activator.CreateInstance(type);
}

throw new InvalidOperationException("Could not find the type '" + typeName + "'.");
#else
return (T)Activator.CreateInstance(Type.GetType(typeName, true, true));
#endif
}
catch (Exception e)
{
throw new InvalidOperationException("Could not instantiate the type '" + typeName + "'. Try specifying the type with the assembly, e.g 'assemblyName:typeName'.", e);
}
}

private string[] GetAllDirectories(string rootDirectory)
{
Expand Down
4 changes: 0 additions & 4 deletions src/NSwag.Commands/Commands/AssemblyOutputCommandBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -41,9 +41,5 @@ public string[] ReferencePaths
get { return Settings.AssemblySettings.ReferencePaths; }
set { Settings.AssemblySettings.ReferencePaths = value; }
}

/// <summary>Creates a new generator instance.</summary>
/// <returns>The generator.</returns>
protected abstract Task<TGenerator> CreateGeneratorAsync();
}
}
9 changes: 1 addition & 8 deletions src/NSwag.Commands/Commands/AssemblyTypeToSwaggerCommand.cs
Original file line number Diff line number Diff line change
Expand Up @@ -91,20 +91,13 @@ public async Task<SwaggerDocument> RunAsync()
{
return await Task.Run(async () =>
{
var generator = await CreateGeneratorAsync();
var generator = new AssemblyTypeToSwaggerGenerator(Settings);
var document = await generator.GenerateAsync(ClassNames).ConfigureAwait(false);
#if DEBUG
var json = document.ToJson();
#endif
return document;
});
}

/// <summary>Creates a new generator instance.</summary>
/// <returns>The generator.</returns>
protected override Task<AssemblyTypeToSwaggerGenerator> CreateGeneratorAsync()
{
return Task.FromResult(new AssemblyTypeToSwaggerGenerator(Settings));
}
}
}
3 changes: 2 additions & 1 deletion src/NSwag.Commands/Commands/ListTypesCommand.cs
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,8 @@ public override async Task<object> RunAsync(CommandLineProcessor processor, ICon
});
}

protected override async Task<AssemblyTypeToSwaggerGenerator> CreateGeneratorAsync()
/// <exception cref="InvalidOperationException">Configuraiton file does not contain AssemblyTypeToSwagger settings.</exception>
protected async Task<AssemblyTypeToSwaggerGenerator> CreateGeneratorAsync()
{
if (!string.IsNullOrEmpty(File))
{
Expand Down
4 changes: 1 addition & 3 deletions src/NSwag.Commands/Commands/ListWebApiControllersCommand.cs
Original file line number Diff line number Diff line change
Expand Up @@ -47,10 +47,8 @@ public override async Task<object> RunAsync(CommandLineProcessor processor, ICon
});
}

/// <summary>Creates a new generator instance.</summary>
/// <returns>The generator.</returns>
/// <exception cref="InvalidOperationException">Configuraiton file does not contain WebApiToSwagger settings.</exception>
protected override async Task<WebApiAssemblyToSwaggerGenerator> CreateGeneratorAsync()
private async Task<WebApiAssemblyToSwaggerGenerator> CreateGeneratorAsync()
{
if (!string.IsNullOrEmpty(File))
{
Expand Down
8 changes: 8 additions & 0 deletions src/NSwag.Commands/Commands/SwaggerToCSharpCommand.cs
Original file line number Diff line number Diff line change
Expand Up @@ -198,5 +198,13 @@ public bool GenerateImmutableDictionaryProperties
get { return Settings.CSharpGeneratorSettings.GenerateImmutableDictionaryProperties; }
set { Settings.CSharpGeneratorSettings.GenerateImmutableDictionaryProperties = value; }
}

[Argument(Name = "JsonSerializerSettingsTransformationMethod", IsRequired = false,
Description = "The name of a static method which is called to transform the JsonSerializerSettings used in the generated ToJson()/FromJson() methods (default: none).")]
public string JsonSerializerSettingsTransformationMethod
{
get { return Settings.CSharpGeneratorSettings.JsonSerializerSettingsTransformationMethod; }
set { Settings.CSharpGeneratorSettings.JsonSerializerSettingsTransformationMethod = value; }
}
}
}
24 changes: 15 additions & 9 deletions src/NSwag.Commands/Commands/WebApiToSwaggerCommand.cs
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,6 @@ public bool IgnoreObsoleteProperties
[Argument(Name = "ServiceSchemes", IsRequired = false, Description = "Overrides the allowed schemes of the web service (optional, comma separated, 'http', 'https', 'ws', 'wss').")]
public string[] ServiceSchemes { get; set; }


[Argument(Name = "InfoTitle", IsRequired = false, Description = "Specify the title of the Swagger specification.")]
public string InfoTitle
{
Expand All @@ -160,6 +159,20 @@ public string InfoVersion
[Argument(Name = "DocumentTemplate", IsRequired = false, Description = "Specifies the Swagger document template (may be a path or JSON, default: none).")]
public string DocumentTemplate { get; set; }

[Argument(Name = "DocumentProcessors", IsRequired = false, Description = "Gets the document processor type names in the form 'assemblyName:fullTypeName' or 'fullTypeName').")]
public string[] DocumentProcessorTypes
{
get { return Settings.DocumentProcessorTypes; }
set { Settings.DocumentProcessorTypes = value; }
}

[Argument(Name = "OperationProcessors", IsRequired = false, Description = "Gets the operation processor type names in the form 'assemblyName:fullTypeName' or 'fullTypeName').")]
public string[] OperationProcessorTypes
{
get { return Settings.OperationProcessorTypes; }
set { Settings.OperationProcessorTypes = value; }
}

public override async Task<object> RunAsync(CommandLineProcessor processor, IConsoleHost host)
{
var service = await RunAsync();
Expand All @@ -181,7 +194,7 @@ public async Task<SwaggerDocument> RunAsync()
else
Settings.DocumentTemplate = null;

var generator = await CreateGeneratorAsync();
var generator = new WebApiAssemblyToSwaggerGenerator(Settings);

var controllerNames = ControllerNames.Where(s => !string.IsNullOrWhiteSpace(s)).Distinct().ToList();
if (!controllerNames.Any() && Settings.AssemblySettings.AssemblyPaths?.Length > 0)
Expand Down Expand Up @@ -209,12 +222,5 @@ public async Task<SwaggerDocument> RunAsync()
return document;
});
}

/// <summary>Creates a new generator instance.</summary>
/// <returns>The generator.</returns>
protected override Task<WebApiAssemblyToSwaggerGenerator> CreateGeneratorAsync()
{
return Task.FromResult(new WebApiAssemblyToSwaggerGenerator(Settings));
}
}
}
6 changes: 4 additions & 2 deletions src/NSwag.Commands/NSwagDocument.cs
Original file line number Diff line number Diff line change
Expand Up @@ -214,11 +214,13 @@ private async Task<string> StartCommandLineProcessAsync(string command)
{
var processStart = new ProcessStartInfo(GetProgramName(), GetArgumentsPrefix() + command);
processStart.RedirectStandardOutput = true;
processStart.RedirectStandardError = true;
processStart.UseShellExecute = false;
processStart.CreateNoWindow = true;

var process = Process.Start(processStart);
var output = await process.StandardOutput.ReadToEndAsync();
var output = await process.StandardOutput.ReadToEndAsync() +
"\n\n" + await process.StandardError.ReadToEndAsync();

if (process.ExitCode != 0)
{
Expand Down Expand Up @@ -270,7 +272,7 @@ private string GetProgramName()
#if NET451

var runtime = Runtime != Runtime.Default ? Runtime : RuntimeUtilities.CurrentRuntime;
if (runtime == Runtime.WinX64)
if (runtime == Runtime.WinX64 || runtime == Runtime.Debug)
return System.IO.Path.Combine(RootBinaryDirectory, "Win/nswag.exe");
else if (runtime == Runtime.WinX86)
return System.IO.Path.Combine(RootBinaryDirectory, "Win/nswag.x86.exe");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,11 @@
using System.Reflection;
using System.Threading.Tasks;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using NJsonSchema;
using NSwag.AssemblyLoader;
using NSwag.AssemblyLoader.Utilities;
using NSwag.Commands.SwaggerGeneration;
using NSwag.SwaggerGeneration.WebApi;
using NSwag.SwaggerGeneration.Processors;

#if !FullNet
using NJsonSchema.Infrastructure;
Expand Down Expand Up @@ -99,7 +98,7 @@ internal string GenerateForControllers(IEnumerable<string> controllerClassNames,

private async Task<string> GenerateForControllersAsync(IEnumerable<string> controllerClassNames, string settingsData)
{
var settings = JsonConvert.DeserializeObject<WebApiAssemblyToSwaggerGeneratorSettings>(settingsData);
var settings = CreateSettings(settingsData);

RegisterReferencePaths(GetAllReferencePaths(settings));
var controllers = await GetControllerTypesAsync(controllerClassNames, settings);
Expand All @@ -109,6 +108,29 @@ private async Task<string> GenerateForControllersAsync(IEnumerable<string> contr
return document.ToJson();
}

private WebApiAssemblyToSwaggerGeneratorSettings CreateSettings(string settingsData)
{
var settings = JsonConvert.DeserializeObject<WebApiAssemblyToSwaggerGeneratorSettings>(settingsData);
if (settings.DocumentProcessorTypes != null)
{
foreach (var p in settings.DocumentProcessorTypes)
{
var processor = CreateInstance<IDocumentProcessor>(p);
settings.DocumentProcessors.Add(processor);
}
}

if (settings.OperationProcessorTypes != null)
{
foreach (var p in settings.OperationProcessorTypes)
{
var processor = CreateInstance<IOperationProcessor>(p);
settings.OperationProcessors.Add(processor);
}
}
return settings;
}

/// <exception cref="InvalidOperationException">No assembly paths have been provided.</exception>
#pragma warning disable 1998
private async Task<IEnumerable<Type>> GetControllerTypesAsync(IEnumerable<string> controllerClassNames, WebApiAssemblyToSwaggerGeneratorSettings settings)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,6 @@
// <author>Rico Suter, [email protected]</author>
//-----------------------------------------------------------------------

using NSwag.SwaggerGeneration;
using NSwag.SwaggerGeneration.WebApi;

namespace NSwag.SwaggerGeneration.WebApi
{
/// <summary>Settings for the WebApiAssemblyToSwaggerGenerator.</summary>
Expand All @@ -22,5 +19,11 @@ public WebApiAssemblyToSwaggerGeneratorSettings()

/// <summary>Gets or sets the Web API assembly paths.</summary>
public AssemblySettings AssemblySettings { get; }

/// <summary>Gets or sets the additional document processor type names in the form 'assemblyName:fullTypeName' or 'fullTypeName' which are instantiated during generation.</summary>
public string[] DocumentProcessorTypes { get; set; }

/// <summary>Gets or sets the additional operation processor type names in the form 'assemblyName:fullTypeName' or 'fullTypeName' which are instantiated during generation.</summary>
public string[] OperationProcessorTypes { get; set; }
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ public async Task When_IncludedVersions_are_set_then_only_these_are_available_in
{
//// Arrange
var settings = new WebApiToSwaggerGeneratorSettings();
settings.OperationProcessors.Get<ApiVersionProcessor>().IncludedVersions.Add("1");
settings.OperationProcessors.TryGet<ApiVersionProcessor>().IncludedVersions.Add("1");

var generator = new WebApiToSwaggerGenerator(settings);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,20 @@
//-----------------------------------------------------------------------

using System.Collections.ObjectModel;
using System.Linq;
using NSwag.SwaggerGeneration.Processors;

namespace NSwag.SwaggerGeneration.WebApi
{
/// <summary>A collection of docment processors.</summary>
public class DocumentProcessorCollection : Collection<IDocumentProcessor>
{

/// <summary>Gets an operation processor of the specified type.</summary>
/// <typeparam name="T">The operation processor type.</typeparam>
/// <returns>The operation processor.</returns>
public T TryGet<T>()
{
return (T)this.FirstOrDefault(p => p is T);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,9 @@ public class OperationProcessorCollection : Collection<IOperationProcessor>
/// <summary>Gets an operation processor of the specified type.</summary>
/// <typeparam name="T">The operation processor type.</typeparam>
/// <returns>The operation processor.</returns>
public T Get<T>()
public T TryGet<T>()
{
return (T)this.First(p => p is T);
return (T)this.FirstOrDefault(p => p is T);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,11 @@ public class OperationSecurityScopeProcessor : IOperationProcessor
{
private readonly string _name;

/// <summary>Initializes a new instance of the <see cref="OperationSecurityScopeProcessor"/> class with 'Bearer' name.</summary>
public OperationSecurityScopeProcessor() : this("Bearer")
{
}

/// <summary>Initializes a new instance of the <see cref="OperationSecurityScopeProcessor"/> class.</summary>
/// <param name="name">The security definition name.</param>
public OperationSecurityScopeProcessor(string name)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,12 @@
VerticalScrollBarVisibility="Visible"
Margin="0,0,0,12" />

<TextBlock Text="JsonSerializerSettings transformation method name" FontWeight="Bold"
Margin="0,0,0,6" />
<TextBox Text="{Binding Command.JsonSerializerSettingsTransformationMethod, Mode=TwoWay}"
ToolTip="JsonSerializerSettingsTransformationMethod"
Margin="0,0,0,12" />

<CheckBox IsChecked="{Binding Command.GenerateOptionalParameters, Mode=TwoWay}"
ToolTip="GenerateOptionalParameters"
Content="Generate optional parameters (reorder parameters (required first, optional at the end) and generate optional parameters)" Margin="0,0,0,12" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,25 @@
<TextBlock Text="Default URL Template" FontWeight="Bold" Margin="0,0,0,6" />
<TextBlock Text="Default for Web API: 'api/{controller}/{id}'; for MVC projects: '{controller}/{action}/{id?}'" TextWrapping="Wrap" Margin="0,0,0,6" />
<TextBox Text="{Binding Command.DefaultUrlTemplate, Mode=TwoWay}" Margin="0,0,0,12" ToolTip="DefaultUrlTemplate" />


<TextBlock Text="Document processors (type names in the form 'assemblyName:fullTypeName' or 'fullTypeName', optional, multiple on separate lines)"
TextWrapping="Wrap" FontWeight="Bold" Margin="0,0,0,6" />
<TextBox Text="{Binding Command.DocumentProcessorTypes, Mode=TwoWay, Converter={StaticResource StringArrayConverter}}"
ToolTip="DocumentProcessors"
Height="52"
AcceptsReturn="True"
VerticalScrollBarVisibility="Visible"
Margin="0,0,0,12" />

<TextBlock Text="Operation processors (type names in the form 'assemblyName:fullTypeName' or 'fullTypeName', optional, multiple on separate lines)"
TextWrapping="Wrap" FontWeight="Bold" Margin="0,0,0,6" />
<TextBox Text="{Binding Command.OperationProcessorTypes, Mode=TwoWay, Converter={StaticResource StringArrayConverter}}"
ToolTip="OperationProcessors"
Height="52"
AcceptsReturn="True"
VerticalScrollBarVisibility="Visible"
Margin="0,0,0,12" />

<GroupBox Header="Swagger Information" Margin="0,0,0,8">
<StackPanel Margin="4,8,4,-8">
<TextBlock Text="Title" FontWeight="Bold" Margin="0,0,0,6" />
Expand Down

0 comments on commit 0aad9f1

Please sign in to comment.