Update/ordering webappbuilderpull/2099/head
@ -0,0 +1,17 @@ | |||||
global using Autofac.Extensions.DependencyInjection; | |||||
global using Microsoft.AspNetCore.Hosting; | |||||
global using Microsoft.Extensions.Configuration; | |||||
global using Microsoft.Extensions.Hosting; | |||||
global using Ordering.BackgroundTasks.Extensions; | |||||
global using Serilog; | |||||
global using System.IO; | |||||
global using HealthChecks.UI.Client; | |||||
global using Microsoft.AspNetCore.Builder; | |||||
global using Microsoft.AspNetCore.Diagnostics.HealthChecks; | |||||
global using Microsoft.Extensions.Configuration; | |||||
global using Microsoft.Extensions.DependencyInjection; | |||||
global using Microsoft.Extensions.Logging; | |||||
global using Ordering.BackgroundTasks.Extensions; | |||||
global using Ordering.BackgroundTasks.Services; | |||||
global using System; | |||||
global using Ordering.BackgroundTasks; |
@ -1,35 +1,74 @@ | |||||
using Autofac.Extensions.DependencyInjection; | |||||
using Microsoft.AspNetCore.Hosting; | |||||
using Microsoft.Extensions.Configuration; | |||||
using Microsoft.Extensions.Hosting; | |||||
using Ordering.BackgroundTasks.Extensions; | |||||
using Serilog; | |||||
using System.IO; | |||||
var appName = "Ordering.BackgroundTasks"; | |||||
var builder = WebApplication.CreateBuilder(new WebApplicationOptions | |||||
{ | |||||
Args = args, | |||||
ApplicationName = typeof(Program).Assembly.FullName | |||||
}); | |||||
builder.Configuration.SetBasePath(Directory.GetCurrentDirectory()); | |||||
builder.Configuration.AddJsonFile("appsettings.json", optional: true); | |||||
builder.Configuration.AddJsonFile($"appsettings.{builder.Environment.EnvironmentName}.json", optional: true); | |||||
builder.Configuration.AddEnvironmentVariables(); | |||||
builder.Host.UseSerilog(CreateSerilogLogger(builder.Configuration)); | |||||
builder.Services.AddCustomHealthCheck(builder.Configuration) | |||||
.Configure<BackgroundTaskSettings>(builder.Configuration) | |||||
.AddOptions() | |||||
.AddHostedService<GracePeriodManagerService>() | |||||
.AddEventBus(builder.Configuration); | |||||
var app = builder.Build(); | |||||
if (app.Environment.IsDevelopment()) | |||||
{ | |||||
app.UseDeveloperExceptionPage(); | |||||
} | |||||
else | |||||
{ | |||||
app.UseExceptionHandler("/Home/Error"); | |||||
} | |||||
app.UseRouting(); | |||||
namespace Ordering.BackgroundTasks | |||||
app.MapHealthChecks("/hc", new HealthCheckOptions() | |||||
{ | { | ||||
public class Program | |||||
{ | |||||
public static readonly string AppName = typeof(Program).Assembly.GetName().Name; | |||||
Predicate = _ => true, | |||||
ResponseWriter = UIResponseWriter.WriteHealthCheckUIResponse | |||||
}); | |||||
app.MapHealthChecks("/liveness", new HealthCheckOptions | |||||
{ | |||||
Predicate = r => r.Name.Contains("self") | |||||
}); | |||||
public static void Main(string[] args) | |||||
{ | |||||
CreateHostBuilder(args).Run(); | |||||
} | |||||
try | |||||
{ | |||||
Log.Information("Starting web host ({ApplicationContext})...", Program.AppName); | |||||
await app.RunAsync(); | |||||
public static IHost CreateHostBuilder(string[] args) => | |||||
Host.CreateDefaultBuilder(args) | |||||
.UseServiceProviderFactory(new AutofacServiceProviderFactory()) | |||||
.ConfigureWebHostDefaults(webBuilder => webBuilder.UseStartup<Startup>()) | |||||
.ConfigureAppConfiguration((host, builder) => | |||||
{ | |||||
builder.SetBasePath(Directory.GetCurrentDirectory()); | |||||
builder.AddJsonFile("appsettings.json", optional: true); | |||||
builder.AddJsonFile($"appsettings.{host.HostingEnvironment.EnvironmentName}.json", optional: true); | |||||
builder.AddEnvironmentVariables(); | |||||
builder.AddCommandLine(args); | |||||
}) | |||||
.ConfigureLogging((host, builder) => builder.UseSerilog(host.Configuration).AddSerilog()) | |||||
.Build(); | |||||
} | |||||
return 0; | |||||
} | |||||
catch (Exception ex) | |||||
{ | |||||
Log.Fatal(ex, "Program terminated unexpectedly ({ApplicationContext})!", Program.AppName); | |||||
return 1; | |||||
} | |||||
finally | |||||
{ | |||||
Log.CloseAndFlush(); | |||||
} | |||||
Serilog.ILogger CreateSerilogLogger(IConfiguration configuration) | |||||
{ | |||||
var seqServerUrl = configuration["Serilog:SeqServerUrl"]; | |||||
var logstashUrl = configuration["Serilog:LogstashgUrl"]; | |||||
return new LoggerConfiguration() | |||||
.MinimumLevel.Verbose() | |||||
.Enrich.WithProperty("ApplicationContext", Program.AppName) | |||||
.Enrich.FromLogContext() | |||||
.WriteTo.Console() | |||||
.WriteTo.Seq(string.IsNullOrWhiteSpace(seqServerUrl) ? "http://seq" : seqServerUrl) | |||||
.WriteTo.Http(string.IsNullOrWhiteSpace(logstashUrl) ? "http://logstash:8080" : logstashUrl, null) | |||||
.ReadFrom.Configuration(configuration) | |||||
.CreateLogger(); | |||||
} | |||||
public partial class Program | |||||
{ | |||||
public static string Namespace = typeof(Program).Assembly.GetName().Name; | |||||
public static string AppName = Namespace.Substring(Namespace.LastIndexOf('.', Namespace.LastIndexOf('.') - 1) + 1); | |||||
} | } |
@ -1,48 +0,0 @@ | |||||
namespace Ordering.BackgroundTasks | |||||
{ | |||||
using HealthChecks.UI.Client; | |||||
using Microsoft.AspNetCore.Builder; | |||||
using Microsoft.AspNetCore.Diagnostics.HealthChecks; | |||||
using Microsoft.Extensions.Configuration; | |||||
using Microsoft.Extensions.DependencyInjection; | |||||
using Microsoft.Extensions.Logging; | |||||
using Ordering.BackgroundTasks.Extensions; | |||||
using Ordering.BackgroundTasks.Services; | |||||
public class Startup | |||||
{ | |||||
public Startup(IConfiguration configuration) | |||||
{ | |||||
Configuration = configuration; | |||||
} | |||||
public IConfiguration Configuration { get; } | |||||
public virtual void ConfigureServices(IServiceCollection services) | |||||
{ | |||||
services.AddCustomHealthCheck(this.Configuration) | |||||
.Configure<BackgroundTaskSettings>(this.Configuration) | |||||
.AddOptions() | |||||
.AddHostedService<GracePeriodManagerService>() | |||||
.AddEventBus(this.Configuration); | |||||
} | |||||
public void Configure(IApplicationBuilder app, ILoggerFactory loggerFactory) | |||||
{ | |||||
app.UseRouting(); | |||||
app.UseEndpoints(endpoints => | |||||
{ | |||||
endpoints.MapHealthChecks("/hc", new HealthCheckOptions() | |||||
{ | |||||
Predicate = _ => true, | |||||
ResponseWriter = UIResponseWriter.WriteHealthCheckUIResponse | |||||
}); | |||||
endpoints.MapHealthChecks("/liveness", new HealthCheckOptions | |||||
{ | |||||
Predicate = r => r.Name.Contains("self") | |||||
}); | |||||
}); | |||||
} | |||||
} | |||||
} |
@ -1,251 +0,0 @@ | |||||
namespace Microsoft.eShopOnContainers.Services.Ordering.SignalrHub; | |||||
public class Startup | |||||
{ | |||||
public Startup(IConfiguration configuration) | |||||
{ | |||||
Configuration = configuration; | |||||
} | |||||
public IConfiguration Configuration { get; } | |||||
// This method gets called by the runtime. Use this method to add services to the container. | |||||
// For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940 | |||||
public IServiceProvider ConfigureServices(IServiceCollection services) | |||||
{ | |||||
services | |||||
.AddCustomHealthCheck(Configuration) | |||||
.AddCors(options => | |||||
{ | |||||
options.AddPolicy("CorsPolicy", | |||||
builder => builder | |||||
.AllowAnyMethod() | |||||
.AllowAnyHeader() | |||||
.SetIsOriginAllowed((host) => true) | |||||
.AllowCredentials()); | |||||
}); | |||||
if (Configuration.GetValue<string>("IsClusterEnv") == bool.TrueString) | |||||
{ | |||||
services | |||||
.AddSignalR() | |||||
.AddStackExchangeRedis(Configuration["SignalrStoreConnectionString"]); | |||||
} | |||||
else | |||||
{ | |||||
services.AddSignalR(); | |||||
} | |||||
if (Configuration.GetValue<bool>("AzureServiceBusEnabled")) | |||||
{ | |||||
services.AddSingleton<IServiceBusPersisterConnection>(sp => | |||||
{ | |||||
var serviceBusConnectionString = Configuration["EventBusConnection"]; | |||||
var subscriptionClientName = Configuration["SubscriptionClientName"]; | |||||
return new DefaultServiceBusPersisterConnection(serviceBusConnectionString); | |||||
}); | |||||
} | |||||
else | |||||
{ | |||||
services.AddSingleton<IRabbitMQPersistentConnection>(sp => | |||||
{ | |||||
var logger = sp.GetRequiredService<ILogger<DefaultRabbitMQPersistentConnection>>(); | |||||
var factory = new ConnectionFactory() | |||||
{ | |||||
HostName = Configuration["EventBusConnection"], | |||||
DispatchConsumersAsync = true | |||||
}; | |||||
if (!string.IsNullOrEmpty(Configuration["EventBusUserName"])) | |||||
{ | |||||
factory.UserName = Configuration["EventBusUserName"]; | |||||
} | |||||
if (!string.IsNullOrEmpty(Configuration["EventBusPassword"])) | |||||
{ | |||||
factory.Password = Configuration["EventBusPassword"]; | |||||
} | |||||
var retryCount = 5; | |||||
if (!string.IsNullOrEmpty(Configuration["EventBusRetryCount"])) | |||||
{ | |||||
retryCount = int.Parse(Configuration["EventBusRetryCount"]); | |||||
} | |||||
return new DefaultRabbitMQPersistentConnection(factory, logger, retryCount); | |||||
}); | |||||
} | |||||
ConfigureAuthService(services); | |||||
RegisterEventBus(services); | |||||
services.AddOptions(); | |||||
//configure autofac | |||||
var container = new ContainerBuilder(); | |||||
container.RegisterModule(new ApplicationModule()); | |||||
container.Populate(services); | |||||
return new AutofacServiceProvider(container.Build()); | |||||
} | |||||
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline. | |||||
public void Configure(IApplicationBuilder app, ILoggerFactory loggerFactory) | |||||
{ | |||||
//loggerFactory.AddConsole(Configuration.GetSection("Logging")); | |||||
//loggerFactory.AddDebug(); | |||||
//loggerFactory.AddAzureWebAppDiagnostics(); | |||||
//loggerFactory.AddApplicationInsights(app.ApplicationServices, LogLevel.Trace); | |||||
var pathBase = Configuration["PATH_BASE"]; | |||||
if (!string.IsNullOrEmpty(pathBase)) | |||||
{ | |||||
loggerFactory.CreateLogger<Startup>().LogDebug("Using PATH BASE '{pathBase}'", pathBase); | |||||
app.UsePathBase(pathBase); | |||||
} | |||||
app.UseRouting(); | |||||
app.UseCors("CorsPolicy"); | |||||
app.UseAuthentication(); | |||||
app.UseAuthorization(); | |||||
app.UseEndpoints(endpoints => | |||||
{ | |||||
endpoints.MapHealthChecks("/hc", new HealthCheckOptions() | |||||
{ | |||||
Predicate = _ => true, | |||||
ResponseWriter = UIResponseWriter.WriteHealthCheckUIResponse | |||||
}); | |||||
endpoints.MapHealthChecks("/liveness", new HealthCheckOptions | |||||
{ | |||||
Predicate = r => r.Name.Contains("self") | |||||
}); | |||||
endpoints.MapHub<NotificationsHub>("/hub/notificationhub"); | |||||
}); | |||||
ConfigureEventBus(app); | |||||
} | |||||
private void ConfigureEventBus(IApplicationBuilder app) | |||||
{ | |||||
var eventBus = app.ApplicationServices.GetRequiredService<IEventBus>(); | |||||
eventBus.Subscribe<OrderStatusChangedToAwaitingValidationIntegrationEvent, OrderStatusChangedToAwaitingValidationIntegrationEventHandler>(); | |||||
eventBus.Subscribe<OrderStatusChangedToPaidIntegrationEvent, OrderStatusChangedToPaidIntegrationEventHandler>(); | |||||
eventBus.Subscribe<OrderStatusChangedToStockConfirmedIntegrationEvent, OrderStatusChangedToStockConfirmedIntegrationEventHandler>(); | |||||
eventBus.Subscribe<OrderStatusChangedToShippedIntegrationEvent, OrderStatusChangedToShippedIntegrationEventHandler>(); | |||||
eventBus.Subscribe<OrderStatusChangedToCancelledIntegrationEvent, OrderStatusChangedToCancelledIntegrationEventHandler>(); | |||||
eventBus.Subscribe<OrderStatusChangedToSubmittedIntegrationEvent, OrderStatusChangedToSubmittedIntegrationEventHandler>(); | |||||
} | |||||
private void ConfigureAuthService(IServiceCollection services) | |||||
{ | |||||
// prevent from mapping "sub" claim to nameidentifier. | |||||
JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Remove("sub"); | |||||
var identityUrl = Configuration.GetValue<string>("IdentityUrl"); | |||||
services.AddAuthentication("Bearer").AddJwtBearer(options => | |||||
{ | |||||
options.Authority = identityUrl; | |||||
options.RequireHttpsMetadata = false; | |||||
options.Audience = "orders.signalrhub"; | |||||
options.TokenValidationParameters.ValidateAudience = false; | |||||
options.Events = new JwtBearerEvents | |||||
{ | |||||
OnMessageReceived = context => | |||||
{ | |||||
var accessToken = context.Request.Query["access_token"]; | |||||
var path = context.HttpContext.Request.Path; | |||||
if (!string.IsNullOrEmpty(accessToken) && (path.StartsWithSegments("/hub/notificationhub"))) | |||||
{ | |||||
context.Token = accessToken; | |||||
} | |||||
return Task.CompletedTask; | |||||
} | |||||
}; | |||||
}); | |||||
services.AddAuthorization(options => | |||||
{ | |||||
options.AddPolicy("ApiScope", policy => | |||||
{ | |||||
policy.RequireAuthenticatedUser(); | |||||
policy.RequireClaim("scope", "orders.signalrhub"); | |||||
}); | |||||
}); | |||||
} | |||||
private void RegisterEventBus(IServiceCollection services) | |||||
{ | |||||
if (Configuration.GetValue<bool>("AzureServiceBusEnabled")) | |||||
{ | |||||
services.AddSingleton<IEventBus, EventBusServiceBus>(sp => | |||||
{ | |||||
var serviceBusPersisterConnection = sp.GetRequiredService<IServiceBusPersisterConnection>(); | |||||
var logger = sp.GetRequiredService<ILogger<EventBusServiceBus>>(); | |||||
var eventBusSubcriptionsManager = sp.GetRequiredService<IEventBusSubscriptionsManager>(); | |||||
string subscriptionName = Configuration["SubscriptionClientName"]; | |||||
return new EventBusServiceBus(serviceBusPersisterConnection, logger, | |||||
eventBusSubcriptionsManager, sp, subscriptionName); | |||||
}); | |||||
} | |||||
else | |||||
{ | |||||
services.AddSingleton<IEventBus, EventBusRabbitMQ>(sp => | |||||
{ | |||||
var subscriptionClientName = Configuration["SubscriptionClientName"]; | |||||
var rabbitMQPersistentConnection = sp.GetRequiredService<IRabbitMQPersistentConnection>(); | |||||
var logger = sp.GetRequiredService<ILogger<EventBusRabbitMQ>>(); | |||||
var eventBusSubcriptionsManager = sp.GetRequiredService<IEventBusSubscriptionsManager>(); | |||||
var retryCount = 5; | |||||
if (!string.IsNullOrEmpty(Configuration["EventBusRetryCount"])) | |||||
{ | |||||
retryCount = int.Parse(Configuration["EventBusRetryCount"]); | |||||
} | |||||
return new EventBusRabbitMQ(rabbitMQPersistentConnection, logger, sp, eventBusSubcriptionsManager, subscriptionClientName, retryCount); | |||||
}); | |||||
} | |||||
services.AddSingleton<IEventBusSubscriptionsManager, InMemoryEventBusSubscriptionsManager>(); | |||||
} | |||||
} | |||||
public static class CustomExtensionMethods | |||||
{ | |||||
public static IServiceCollection AddCustomHealthCheck(this IServiceCollection services, IConfiguration configuration) | |||||
{ | |||||
var hcBuilder = services.AddHealthChecks(); | |||||
hcBuilder.AddCheck("self", () => HealthCheckResult.Healthy()); | |||||
if (configuration.GetValue<bool>("AzureServiceBusEnabled")) | |||||
{ | |||||
hcBuilder | |||||
.AddAzureServiceBusTopic( | |||||
configuration["EventBusConnection"], | |||||
topicName: "eshop_event_bus", | |||||
name: "signalr-servicebus-check", | |||||
tags: new string[] { "servicebus" }); | |||||
} | |||||
else | |||||
{ | |||||
hcBuilder | |||||
.AddRabbitMQ( | |||||
$"amqp://{configuration["EventBusConnection"]}", | |||||
name: "signalr-rabbitmqbus-check", | |||||
tags: new string[] { "rabbitmqbus" }); | |||||
} | |||||
return services; | |||||
} | |||||
} |
@ -1,132 +0,0 @@ | |||||
############################### | |||||
# Core EditorConfig Options # | |||||
############################### | |||||
root = true | |||||
# All files | |||||
[*] | |||||
indent_style = space | |||||
# XML project files | |||||
[*.{csproj,vbproj,vcxproj,vcxproj.filters,proj,projitems,shproj}] | |||||
indent_size = 2 | |||||
# XML config files | |||||
[*.{props,targets,ruleset,config,nuspec,resx,vsixmanifest,vsct}] | |||||
indent_size = 2 | |||||
# Code files | |||||
[*.{cs,csx,vb,vbx}] | |||||
indent_size = 4 | |||||
insert_final_newline = true | |||||
charset = utf-8-bom | |||||
############################### | |||||
# .NET Coding Conventions # | |||||
############################### | |||||
[*.{cs,vb}] | |||||
# Organize usings | |||||
dotnet_sort_system_directives_first = true | |||||
# this. preferences | |||||
dotnet_style_qualification_for_field = false:silent | |||||
dotnet_style_qualification_for_property = false:silent | |||||
dotnet_style_qualification_for_method = false:silent | |||||
dotnet_style_qualification_for_event = false:silent | |||||
# Language keywords vs BCL types preferences | |||||
dotnet_style_predefined_type_for_locals_parameters_members = true:silent | |||||
dotnet_style_predefined_type_for_member_access = true:silent | |||||
# Parentheses preferences | |||||
dotnet_style_parentheses_in_arithmetic_binary_operators = always_for_clarity:silent | |||||
dotnet_style_parentheses_in_relational_binary_operators = always_for_clarity:silent | |||||
dotnet_style_parentheses_in_other_binary_operators = always_for_clarity:silent | |||||
dotnet_style_parentheses_in_other_operators = never_if_unnecessary:silent | |||||
# Modifier preferences | |||||
dotnet_style_require_accessibility_modifiers = for_non_interface_members:silent | |||||
dotnet_style_readonly_field = true:suggestion | |||||
# Expression-level preferences | |||||
dotnet_style_object_initializer = true:suggestion | |||||
dotnet_style_collection_initializer = true:suggestion | |||||
dotnet_style_explicit_tuple_names = true:suggestion | |||||
dotnet_style_null_propagation = true:suggestion | |||||
dotnet_style_coalesce_expression = true:suggestion | |||||
dotnet_style_prefer_is_null_check_over_reference_equality_method = true:silent | |||||
dotnet_style_prefer_inferred_tuple_names = true:suggestion | |||||
dotnet_style_prefer_inferred_anonymous_type_member_names = true:suggestion | |||||
dotnet_style_prefer_auto_properties = true:silent | |||||
dotnet_style_prefer_conditional_expression_over_assignment = true:silent | |||||
dotnet_style_prefer_conditional_expression_over_return = true:silent | |||||
############################### | |||||
# Naming Conventions # | |||||
############################### | |||||
# Style Definitions | |||||
dotnet_naming_style.pascal_case_style.capitalization = pascal_case | |||||
# Use PascalCase for constant fields | |||||
dotnet_naming_rule.constant_fields_should_be_pascal_case.severity = suggestion | |||||
dotnet_naming_rule.constant_fields_should_be_pascal_case.symbols = constant_fields | |||||
dotnet_naming_rule.constant_fields_should_be_pascal_case.style = pascal_case_style | |||||
dotnet_naming_symbols.constant_fields.applicable_kinds = field | |||||
dotnet_naming_symbols.constant_fields.applicable_accessibilities = * | |||||
dotnet_naming_symbols.constant_fields.required_modifiers = const | |||||
############################### | |||||
# C# Coding Conventions # | |||||
############################### | |||||
[*.cs] | |||||
# var preferences | |||||
csharp_style_var_for_built_in_types = true:silent | |||||
csharp_style_var_when_type_is_apparent = true:silent | |||||
csharp_style_var_elsewhere = true:silent | |||||
# Expression-bodied members | |||||
csharp_style_expression_bodied_methods = false:silent | |||||
csharp_style_expression_bodied_constructors = false:silent | |||||
csharp_style_expression_bodied_operators = false:silent | |||||
csharp_style_expression_bodied_properties = true:silent | |||||
csharp_style_expression_bodied_indexers = true:silent | |||||
csharp_style_expression_bodied_accessors = true:silent | |||||
# Pattern matching preferences | |||||
csharp_style_pattern_matching_over_is_with_cast_check = true:suggestion | |||||
csharp_style_pattern_matching_over_as_with_null_check = true:suggestion | |||||
# Null-checking preferences | |||||
csharp_style_throw_expression = true:suggestion | |||||
csharp_style_conditional_delegate_call = true:suggestion | |||||
# Modifier preferences | |||||
csharp_preferred_modifier_order = public,private,protected,internal,static,extern,new,virtual,abstract,sealed,override,readonly,unsafe,volatile,async:suggestion | |||||
# Expression-level preferences | |||||
csharp_prefer_braces = true:silent | |||||
csharp_style_deconstructed_variable_declaration = true:suggestion | |||||
csharp_prefer_simple_default_expression = true:suggestion | |||||
csharp_style_prefer_local_over_anonymous_function = true:suggestion | |||||
csharp_style_inlined_variable_declaration = true:suggestion | |||||
############################### | |||||
# C# Formatting Rules # | |||||
############################### | |||||
# New line preferences | |||||
csharp_new_line_before_open_brace = all | |||||
csharp_new_line_before_else = true | |||||
csharp_new_line_before_catch = true | |||||
csharp_new_line_before_finally = true | |||||
csharp_new_line_before_members_in_object_initializers = true | |||||
csharp_new_line_before_members_in_anonymous_types = true | |||||
csharp_new_line_between_query_expression_clauses = true | |||||
# Indentation preferences | |||||
csharp_indent_case_contents = true | |||||
csharp_indent_switch_labels = true | |||||
csharp_indent_labels = flush_left | |||||
# Space preferences | |||||
csharp_space_after_cast = false | |||||
csharp_space_after_keywords_in_control_flow_statements = true | |||||
csharp_space_between_method_call_parameter_list_parentheses = false | |||||
csharp_space_between_method_declaration_parameter_list_parentheses = false | |||||
csharp_space_between_parentheses = false | |||||
csharp_space_before_colon_in_inheritance_clause = true | |||||
csharp_space_after_colon_in_inheritance_clause = true | |||||
csharp_space_around_binary_operators = before_and_after | |||||
csharp_space_between_method_declaration_empty_parameter_list_parentheses = false | |||||
csharp_space_between_method_call_name_and_opening_parenthesis = false | |||||
csharp_space_between_method_call_empty_parameter_list_parentheses = false | |||||
# Wrapping preferences | |||||
csharp_preserve_single_line_statements = true | |||||
csharp_preserve_single_line_blocks = true | |||||
############################### | |||||
# VB Coding Conventions # | |||||
############################### | |||||
[*.vb] | |||||
# Modifier preferences | |||||
visual_basic_preferred_modifier_order = Partial,Default,Private,Protected,Public,Friend,NotOverridable,Overridable,MustOverride,Overloads,Overrides,MustInherit,NotInheritable,Static,Shared,Shadows,ReadOnly,WriteOnly,Dim,Const,WithEvents,Widening,Narrowing,Custom,Async:suggestion |