public static IMvcBuilder AddNaos( this IMvcBuilder mvcBuilder, Action <NaosMvcOptions> optionsAction = null) { var options = new NaosMvcOptions(); optionsAction?.Invoke(options); if (!options.ControllerRegistrations.IsNullOrEmpty()) { mvcBuilder .AddMvcOptions(o => { o.Filters.Add <OperationCancelledExceptionFilter>(); o.Conventions.Add(new GeneratedControllerRouteConvention()); }) .ConfigureApplicationPartManager(o => o .FeatureProviders.Add( new GeneratedRepositoryControllerFeatureProvider(options.ControllerRegistrations))); } mvcBuilder.AddControllersAsServices(); // needed to resolve controllers through di https://andrewlock.net/controller-activation-and-dependency-injection-in-asp-net-core-mvc/ mvcBuilder.AddJsonOptions(o => o.AddDefaultJsonSerializerSettings(options.JsonSerializerSettings)); return(mvcBuilder); }
/// <summary> /// Finds all the types that are <see cref="Controller" /> or <see cref="FeatureController" />and add them to the Api /// as services. /// </summary> /// <param name="builder">The builder</param> /// <param name="services">The services to look into</param> /// <returns>The Mvc builder</returns> public static IMvcBuilder AddControllers(this IMvcBuilder builder, IServiceCollection services) { // Adds Controllers with API endpoints IEnumerable <ServiceDescriptor> controllerTypes = services.Where(s => s.ServiceType.GetTypeInfo().BaseType == typeof(Controller)); foreach (ServiceDescriptor controllerType in controllerTypes) { builder.AddApplicationPart(controllerType.ServiceType.GetTypeInfo().Assembly); } // Adds FeatureControllers with API endpoints. IEnumerable <ServiceDescriptor> featureControllerTypes = services.Where(s => s.ServiceType.GetTypeInfo().BaseType == typeof(FeatureController)); foreach (ServiceDescriptor featureControllerType in featureControllerTypes) { builder.AddApplicationPart(featureControllerType.ServiceType.GetTypeInfo().Assembly); } // Adds ServerNodeContoller with API endpoints. builder.AddApplicationPart(typeof(ServerNodeContoller).Assembly); // Adds PublicController with API endpoints. builder.AddApplicationPart(typeof(PublicController).Assembly); builder.AddControllersAsServices(); return(builder); }
/// <summary> /// Extension method for adding the jellyfin API to the service collection. /// </summary> /// <param name="serviceCollection">The service collection.</param> /// <param name="pluginAssemblies">An IEnumerable containing all plugin assemblies with API controllers.</param> /// <param name="knownProxies">A list of all known proxies to trust for X-Forwarded-For.</param> /// <returns>The MVC builder.</returns> public static IMvcBuilder AddJellyfinApi(this IServiceCollection serviceCollection, IEnumerable <Assembly> pluginAssemblies, IReadOnlyList <string> knownProxies) { IMvcBuilder mvcBuilder = serviceCollection .AddCors() .AddTransient <ICorsPolicyProvider, CorsPolicyProvider>() .Configure <ForwardedHeadersOptions>(options => { options.ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto; for (var i = 0; i < knownProxies.Count; i++) { if (IPAddress.TryParse(knownProxies[i], out var address)) { options.KnownProxies.Add(address); } } }) .AddMvc(opts => { // Allow requester to change between camelCase and PascalCase opts.RespectBrowserAcceptHeader = true; opts.OutputFormatters.Insert(0, new CamelCaseJsonProfileFormatter()); opts.OutputFormatters.Insert(0, new PascalCaseJsonProfileFormatter()); opts.OutputFormatters.Add(new CssOutputFormatter()); opts.OutputFormatters.Add(new XmlOutputFormatter()); }) // Clear app parts to avoid other assemblies being picked up .ConfigureApplicationPartManager(a => a.ApplicationParts.Clear()) .AddApplicationPart(typeof(StartupController).Assembly) .AddJsonOptions(options => { // Update all properties that are set in JsonDefaults var jsonOptions = JsonDefaults.GetPascalCaseOptions(); // From JsonDefaults options.JsonSerializerOptions.ReadCommentHandling = jsonOptions.ReadCommentHandling; options.JsonSerializerOptions.WriteIndented = jsonOptions.WriteIndented; options.JsonSerializerOptions.DefaultIgnoreCondition = jsonOptions.DefaultIgnoreCondition; options.JsonSerializerOptions.NumberHandling = jsonOptions.NumberHandling; options.JsonSerializerOptions.Converters.Clear(); foreach (var converter in jsonOptions.Converters) { options.JsonSerializerOptions.Converters.Add(converter); } // From JsonDefaults.PascalCase options.JsonSerializerOptions.PropertyNamingPolicy = jsonOptions.PropertyNamingPolicy; }); foreach (Assembly pluginAssembly in pluginAssemblies) { mvcBuilder.AddApplicationPart(pluginAssembly); } return(mvcBuilder.AddControllersAsServices()); }
/// <summary> /// Finds all the types that are <see cref="Controller"/> and add them to the Api as services. /// </summary> /// <param name="builder">The builder</param> /// <param name="services">The services to look into</param> /// <returns>The Mvc builder</returns> public static IMvcBuilder AddControllers(this IMvcBuilder builder, IServiceCollection services) { var controllerTypes = services.Where(s => s.ServiceType.GetTypeInfo().BaseType == typeof(Controller)); foreach (var controllerType in controllerTypes) { builder.AddApplicationPart(controllerType.ServiceType.GetTypeInfo().Assembly); } builder.AddControllersAsServices(); return(builder); }
/// <summary> /// Extension method for adding the jellyfin API to the service collection. /// </summary> /// <param name="serviceCollection">The service collection.</param> /// <param name="baseUrl">The base url for the API.</param> /// <param name="pluginAssemblies">An IEnumberable containing all plugin assemblies with API controllers.</param> /// <returns>The MVC builder.</returns> public static IMvcBuilder AddJellyfinApi(this IServiceCollection serviceCollection, string baseUrl, IEnumerable <Assembly> pluginAssemblies) { IMvcBuilder mvcBuilder = serviceCollection .AddCors(options => { options.AddPolicy(ServerCorsPolicy.DefaultPolicyName, ServerCorsPolicy.DefaultPolicy); }) .Configure <ForwardedHeadersOptions>(options => { options.ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto; }) .AddMvc(opts => { opts.UseGeneralRoutePrefix(baseUrl); opts.OutputFormatters.Insert(0, new CamelCaseJsonProfileFormatter()); opts.OutputFormatters.Insert(0, new PascalCaseJsonProfileFormatter()); opts.OutputFormatters.Add(new CssOutputFormatter()); opts.OutputFormatters.Add(new XmlOutputFormatter()); }) // Clear app parts to avoid other assemblies being picked up .ConfigureApplicationPartManager(a => a.ApplicationParts.Clear()) .AddApplicationPart(typeof(StartupController).Assembly) .AddJsonOptions(options => { // Update all properties that are set in JsonDefaults var jsonOptions = JsonDefaults.GetPascalCaseOptions(); // From JsonDefaults options.JsonSerializerOptions.ReadCommentHandling = jsonOptions.ReadCommentHandling; options.JsonSerializerOptions.WriteIndented = jsonOptions.WriteIndented; options.JsonSerializerOptions.DefaultIgnoreCondition = jsonOptions.DefaultIgnoreCondition; options.JsonSerializerOptions.NumberHandling = jsonOptions.NumberHandling; options.JsonSerializerOptions.Converters.Clear(); foreach (var converter in jsonOptions.Converters) { options.JsonSerializerOptions.Converters.Add(converter); } // From JsonDefaults.PascalCase options.JsonSerializerOptions.PropertyNamingPolicy = jsonOptions.PropertyNamingPolicy; }); foreach (Assembly pluginAssembly in pluginAssemblies) { mvcBuilder.AddApplicationPart(pluginAssembly); } return(mvcBuilder.AddControllersAsServices()); }
public static IServiceCollection AddDeploymentMvc(this IServiceCollection services, EnvironmentConfiguration environmentConfiguration, IKeyValueConfiguration configuration, ILogger logger, IApplicationAssemblyResolver applicationAssemblyResolver) { ViewAssemblyLoader.LoadViewAssemblies(logger); var filteredAssemblies = applicationAssemblyResolver.GetAssemblies(); IMvcBuilder mvcBuilder = services.AddMvc( options => { options.InputFormatters.Insert(0, new XWwwFormUrlEncodedFormatter()); options.Filters.Add <ModelValidatorFilterAttribute>(); }) .AddNewtonsoftJson( options => { options.SerializerSettings.Converters.Add(new DateConverter()); options.SerializerSettings.Formatting = Formatting.Indented; }); foreach (Assembly filteredAssembly in filteredAssemblies) { logger.Debug("Adding assembly {Assembly} to MVC application parts", filteredAssembly.FullName); mvcBuilder.AddApplicationPart(filteredAssembly); } var viewAssemblies = AssemblyLoadContext.Default.Assemblies .Where(assembly => !assembly.IsDynamic && (assembly.GetName().Name?.Contains("View") ?? false)) .ToArray(); foreach (var item in viewAssemblies) { mvcBuilder.AddApplicationPart(item); } if (environmentConfiguration.ToHostEnvironment().IsDevelopment() || configuration.ValueOrDefault(StartupConstants.RuntimeCompilationEnabled)) { mvcBuilder.AddRazorRuntimeCompilation(); } mvcBuilder .AddControllersAsServices(); services.AddAntiforgery(); return(services); }
internal static IMvcBuilder AddExternalControllers(this IMvcBuilder builder) { List <Assembly> assemblies = new List <Assembly>(); string path = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location); foreach (string dll in Directory.GetFiles(path, "*.dll")) { assemblies.Add(Assembly.LoadFile(dll)); } foreach (var asm in assemblies) { builder.AddApplicationPart(asm); } builder.AddControllersAsServices(); return(builder); }
public static void InstallModules( this IServiceCollection services, string contentRootPath) { LineBotService.ContentRootPath = contentRootPath; #region Internal Module List <Type> result = new List <Type>(); IMvcBuilder mvc = services.AddMvc(); foreach (var assembly in Assembly .GetEntryAssembly() .GetReferencedAssemblies() .Select(Assembly.Load) .Concat(new Assembly[] { Assembly.GetEntryAssembly() })) { mvc = mvc.AddApplicationPart(assembly); Type[] types = null; try { types = assembly.GetTypes(); } catch (ReflectionTypeLoadException e) { Console.WriteLine("[FAIL LOAD]: " + assembly.FullName + ";" + e.InnerException); types = e.Types; } result.AddRange(types); } LineBotService.ReplyModules = new List <(Type, bool)>(); foreach (var type in result) { if (!type.GetInterfaces().Contains(typeof(ILineReplyModule))) { continue; } LineBotService.ReplyModules.Add((type, true)); services.AddScoped(type); } #endregion var pluginsPath = Path.Combine(contentRootPath, "plugins"); Console.WriteLine($"PluginsPath: {pluginsPath}"); if (!Directory.Exists(pluginsPath)) { Console.WriteLine("建立plugins目錄"); Directory.CreateDirectory(pluginsPath); } // plugin Directory.GetDirectories(pluginsPath).ParallelForEachAsync(async module => { Console.WriteLine("Install:" + module); foreach (var dll in Directory.GetFiles(module, "*.dll", SearchOption.AllDirectories)) { System.Runtime.Loader.AssemblyLoadContext.Default .LoadFromAssemblyPath(dll); } foreach (var dll in Directory.GetFiles(module, "*.dll", SearchOption.AllDirectories)) { InstallReplayProcessFromDll(services, mvc, dll); } }).GetAwaiter().GetResult(); mvc = mvc.AddControllersAsServices(); // 停用模組 using (var file = File.Open("disableModules.txt", FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.Read)) { var moduleNames = new StreamReader(file).ReadToEnd()?.Split(',') ?? new string[0]; moduleNames = moduleNames.Select(x => x.Trim()).Where(x => x.Length > 0).ToArray(); foreach (var moduleName in moduleNames) { var moduleIndex = LineBotService.ReplyModules.FindIndex(x => x.type.Name.ToLower() == moduleName.ToLower()); LineBotService.ReplyModules[moduleIndex] = (LineBotService.ReplyModules[moduleIndex].type, false); } } }
/// <summary> /// Extension method for adding the jellyfin API to the service collection. /// </summary> /// <param name="serviceCollection">The service collection.</param> /// <param name="pluginAssemblies">An IEnumerable containing all plugin assemblies with API controllers.</param> /// <param name="config">The <see cref="NetworkConfiguration"/>.</param> /// <returns>The MVC builder.</returns> public static IMvcBuilder AddJellyfinApi(this IServiceCollection serviceCollection, IEnumerable <Assembly> pluginAssemblies, NetworkConfiguration config) { IMvcBuilder mvcBuilder = serviceCollection .AddCors() .AddTransient <ICorsPolicyProvider, CorsPolicyProvider>() .Configure <ForwardedHeadersOptions>(options => { // https://github.com/dotnet/aspnetcore/blob/master/src/Middleware/HttpOverrides/src/ForwardedHeadersMiddleware.cs // Enable debug logging on Microsoft.AspNetCore.HttpOverrides.ForwardedHeadersMiddleware to help investigate issues. options.ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto | ForwardedHeaders.XForwardedHost; if (config.KnownProxies.Length == 0) { options.KnownNetworks.Clear(); options.KnownProxies.Clear(); } else { AddProxyAddresses(config, config.KnownProxies, options); } // Only set forward limit if we have some known proxies or some known networks. if (options.KnownProxies.Count != 0 || options.KnownNetworks.Count != 0) { options.ForwardLimit = null; } }) .AddMvc(opts => { // Allow requester to change between camelCase and PascalCase opts.RespectBrowserAcceptHeader = true; opts.OutputFormatters.Insert(0, new CamelCaseJsonProfileFormatter()); opts.OutputFormatters.Insert(0, new PascalCaseJsonProfileFormatter()); opts.OutputFormatters.Add(new CssOutputFormatter()); opts.OutputFormatters.Add(new XmlOutputFormatter()); opts.ModelBinderProviders.Insert(0, new NullableEnumModelBinderProvider()); }) // Clear app parts to avoid other assemblies being picked up .ConfigureApplicationPartManager(a => a.ApplicationParts.Clear()) .AddApplicationPart(typeof(StartupController).Assembly) .AddJsonOptions(options => { // Update all properties that are set in JsonDefaults var jsonOptions = JsonDefaults.PascalCaseOptions; // From JsonDefaults options.JsonSerializerOptions.ReadCommentHandling = jsonOptions.ReadCommentHandling; options.JsonSerializerOptions.WriteIndented = jsonOptions.WriteIndented; options.JsonSerializerOptions.DefaultIgnoreCondition = jsonOptions.DefaultIgnoreCondition; options.JsonSerializerOptions.NumberHandling = jsonOptions.NumberHandling; options.JsonSerializerOptions.Converters.Clear(); foreach (var converter in jsonOptions.Converters) { options.JsonSerializerOptions.Converters.Add(converter); } // From JsonDefaults.PascalCase options.JsonSerializerOptions.PropertyNamingPolicy = jsonOptions.PropertyNamingPolicy; }); foreach (Assembly pluginAssembly in pluginAssemblies) { mvcBuilder.AddApplicationPart(pluginAssembly); } return(mvcBuilder.AddControllersAsServices()); }
// This method gets called by a runtime. // Use this method to add services to the container public void ConfigureServices(IServiceCollection services) { var hostEnv = services.BuildServiceProvider().GetRequiredService <IHostingEnvironment>(); string configRootPath = services.BuildServiceProvider().GetRequiredService <IHostingEnvironment>().ConfigRootPath(); // // Configuration services.AddSingleton((s) => Configuration); services.AddSingleton <IHttpContextAccessor, HttpContextAccessor>(); // // Logging services.AddApiLogging(); // // Auditing services.AddApiAuditing(); // // Load plugins ModuleConfig modConfig = new ModuleConfig(Path.Combine(configRootPath, "modules.json")); ModuleLoader loader = new ModuleLoader(hostEnv); LoadPlugins(loader, modConfig.Modules); services.AddOptions(); // // CORS services.AddCors(); // // Api Keys services.AddApiKeyProvider(); // // Authentication services.AddAuthentication(); services.AddAuthorization(o => { o.AddPolicy("AccessToken", p => p.RequireAuthenticatedUser().RequireClaim(Core.Security.ClaimTypes.AccessToken)); o.AddPolicy("Administrators", p => p.RequireAuthenticatedUser().RequireRole("Administrators")); o.AddPolicy("AdministrativeGroup", p => p.RequireAuthenticatedUser().RequireAssertion(authContext => IsUserInAdministrators(authContext, Configuration) )); }); // // Antiforgery services.TryAddSingleton <IAntiforgeryTokenStore, AntiForgeryTokenStore>(); services.AddAntiforgery(); services.AddAntiforgery(o => { o.RequireSsl = true; o.CookieName = o.FormFieldName = Core.Http.HeaderNames.XSRF_TOKEN; }); // // MVC IMvcBuilder builder = services.AddMvc(o => { // Replace default json output formatter o.OutputFormatters.RemoveType <AspNetCore.Mvc.Formatters.JsonOutputFormatter>(); var settings = JsonSerializerSettingsProvider.CreateSerializerSettings(); o.OutputFormatters.Add(new JsonOutputFormatter(settings, System.Buffers.ArrayPool <char> .Shared)); // TODO // Workaround filter to fix Object Results returned from controllers // Remove when https://github.com/aspnet/Mvc/issues/4960 is resolved o.Filters.Add(typeof(Fix4960ActionFilter)); o.Filters.Add(typeof(ResourceInfoFilter)); RemoveFilter <UnsupportedContentTypeFilter>(o); }); foreach (var asm in loader.GetAllLoadedAssemblies()) { builder.AddApplicationPart(asm); } builder.AddControllersAsServices(); builder.AddWebApiConventions(); }
public static IMvcBuilder AddSecureApi(this IMvcBuilder builder, IServiceCollection services) { builder.AddApplicationPart(typeof(SecureApiControllerBase).Assembly); builder.AddControllersAsServices(); return(builder); }
// This method gets called by a runtime. // Use this method to add services to the container public void ConfigureServices(IServiceCollection services) { // // IHttpContextAccessor services.AddSingleton <IHttpContextAccessor, HttpContextAccessor>(); // // Logging services.AddApiLogging(); // // Auditing services.AddApiAuditing(); // // Files services.AddFileProvider(); // // Load plugins ModuleConfig modConfig = new ModuleConfig(_hostingEnv.GetConfigPath("modules.json")); ModuleLoader loader = new ModuleLoader(_hostingEnv); LoadPlugins(loader, modConfig.Modules); AdminHost.Instance.ConfigureModules(services); // // CORS services.AddCors(); // // Authentication services.AddBearerAuthentication(); // // Authorization services.AddAuthorizationPolicy(); services.AddConfigurationWriter(_hostingEnv); // // Antiforgery services.TryAddSingleton <IAntiforgeryTokenStore, AntiForgeryTokenStore>(); services.AddAntiforgery(o => { o.RequireSsl = true; o.CookieName = o.FormFieldName = HeaderNames.XSRF_TOKEN; }); // // Caching services.AddMemoryCache(); // // MVC IMvcBuilder builder = services.AddMvc(o => { // Replace default json output formatter o.OutputFormatters.RemoveType <AspNetCore.Mvc.Formatters.JsonOutputFormatter>(); var settings = JsonSerializerSettingsProvider.CreateSerializerSettings(); o.OutputFormatters.Add(new JsonOutputFormatter(settings, System.Buffers.ArrayPool <char> .Shared)); // TODO // Workaround filter to fix Object Results returned from controllers // Remove when https://github.com/aspnet/Mvc/issues/4960 is resolved o.Filters.Add(typeof(Fix4960ActionFilter)); o.Filters.Add(typeof(ActionFoundFilter)); o.Filters.Add(typeof(ResourceInfoFilter)); RemoveFilter <UnsupportedContentTypeFilter>(o); }); foreach (var asm in loader.GetAllLoadedAssemblies()) { builder.AddApplicationPart(asm); } builder.AddControllersAsServices(); builder.AddWebApiConventions(); }
/// <summary> /// Register the specified <paramref name="controllerTypes"/> as services and as a source for controller /// discovery. /// </summary> /// <param name="builder">The <see cref="IMvcBuilder"/>.</param> /// <param name="controllerTypes">A sequence of controller <see cref="Type"/>s to register.</param> /// <returns>The <see cref="IMvcBuilder"/>.</returns> public static IMvcBuilder AddControllersAsServices( this IMvcBuilder builder, params Type[] controllerTypes) { return(builder.AddControllersAsServices(controllerTypes.AsEnumerable())); }