Try your search with a different keyword or use * as a wildcard.
using System.Net;
using System.Threading.RateLimiting;
using Azure.Identity;
using Azure.Storage.Blobs;
using FluentValidation;
using FluentValidation.AspNetCore;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.DataProtection;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.ApplicationParts;
using Microsoft.AspNetCore.Mvc.Infrastructure;
using Microsoft.AspNetCore.Mvc.Razor;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Newtonsoft.Json.Serialization;
using Nop.Core;
using Nop.Core.Configuration;
using Nop.Core.Domain.Common;
using Nop.Core.Http;
using Nop.Core.Infrastructure;
using Nop.Core.Security;
using Nop.Data;
using Nop.Services.Authentication;
using Nop.Services.Authentication.External;
using Nop.Services.Common;
using Nop.Web.Framework.Mvc.ModelBinding;
using Nop.Web.Framework.Mvc.ModelBinding.Binders;
using Nop.Web.Framework.Mvc.Routing;
using Nop.Web.Framework.Security.Captcha;
using Nop.Web.Framework.Themes;
using Nop.Web.Framework.Validators;
using Nop.Web.Framework.WebOptimizer;
using WebMarkupMin.AspNetCore8;
using WebMarkupMin.Core;
using WebMarkupMin.NUglify;
namespace Nop.Web.Framework.Infrastructure.Extensions;
///
/// Represents extensions of IServiceCollection
///
public static class ServiceCollectionExtensions
{
///
/// Configure base application settings
///
/// Collection of service descriptors
/// A builder for web applications and services
public static void ConfigureApplicationSettings(this IServiceCollection services,
WebApplicationBuilder builder)
{
//let the operating system decide what TLS protocol version to use
//see https://docs.microsoft.com/dotnet/framework/network-programming/tls
ServicePointManager.SecurityProtocol = SecurityProtocolType.SystemDefault;
//create default file provider
CommonHelper.DefaultFileProvider = new NopFileProvider(builder.Environment);
//register type finder
var typeFinder = new WebAppTypeFinder();
Singleton.Instance = typeFinder;
services.AddSingleton(typeFinder);
//add configuration parameters
var configurations = typeFinder
.FindClassesOfType()
.Select(configType => (IConfig)Activator.CreateInstance(configType))
.ToList();
foreach (var config in configurations)
builder.Configuration.GetSection(config.Name).Bind(config, options => options.BindNonPublicProperties = true);
var appSettings = AppSettingsHelper.SaveAppSettings(configurations, CommonHelper.DefaultFileProvider, false);
services.AddSingleton(appSettings);
}
///
/// Add services to the application and configure service provider
///
/// Collection of service descriptors
/// A builder for web applications and services
public static void ConfigureApplicationServices(this IServiceCollection services,
WebApplicationBuilder builder)
{
//add accessor to HttpContext
services.AddHttpContextAccessor();
//initialize plugins
var mvcCoreBuilder = services.AddMvcCore();
var pluginConfig = new PluginConfig();
builder.Configuration.GetSection(nameof(PluginConfig)).Bind(pluginConfig, options => options.BindNonPublicProperties = true);
mvcCoreBuilder.PartManager.InitializePlugins(pluginConfig);
//create engine and configure service provider
var engine = EngineContext.Create();
builder.Services.AddRateLimiter(options =>
{
var settings = Singleton.Instance.Get();
options.GlobalLimiter = PartitionedRateLimiter.Create(httpContext =>
RateLimitPartition.GetFixedWindowLimiter(
partitionKey: httpContext.User.Identity?.Name ?? httpContext.Request.Headers.Host.ToString(),
factory: partition => new FixedWindowRateLimiterOptions
{
AutoReplenishment = true,
PermitLimit = settings.PermitLimit,
QueueLimit = settings.QueueCount,
Window = TimeSpan.FromMinutes(1)
}));
options.RejectionStatusCode = settings.RejectionStatusCode;
});
engine.ConfigureServices(services, builder.Configuration);
}
///
/// Register HttpContextAccessor
///
/// Collection of service descriptors
public static void AddHttpContextAccessor(this IServiceCollection services)
{
services.AddSingleton();
}
///
/// Adds services required for anti-forgery support
///
/// Collection of service descriptors
public static void AddAntiForgery(this IServiceCollection services)
{
//override cookie name
services.AddAntiforgery(options =>
{
options.Cookie.Name = $"{NopCookieDefaults.Prefix}{NopCookieDefaults.AntiforgeryCookie}";
options.Cookie.SecurePolicy = CookieSecurePolicy.SameAsRequest;
});
}
///
/// Adds services required for application session state
///
/// Collection of service descriptors
public static void AddHttpSession(this IServiceCollection services)
{
services.AddSession(options =>
{
options.Cookie.Name = $"{NopCookieDefaults.Prefix}{NopCookieDefaults.SessionCookie}";
options.Cookie.HttpOnly = true;
options.Cookie.SecurePolicy = CookieSecurePolicy.SameAsRequest;
});
}
///
/// Adds services required for themes support
///
/// Collection of service descriptors
public static void AddThemes(this IServiceCollection services)
{
if (!DataSettingsManager.IsDatabaseInstalled())
return;
//themes support
services.Configure(options =>
{
options.ViewLocationExpanders.Add(new ThemeableViewLocationExpander());
});
}
///
/// Adds services required for distributed cache
///
/// Collection of service descriptors
public static void AddDistributedCache(this IServiceCollection services)
{
var appSettings = Singleton.Instance;
var distributedCacheConfig = appSettings.Get();
if (!distributedCacheConfig.Enabled)
return;
switch (distributedCacheConfig.DistributedCacheType)
{
case DistributedCacheType.Memory:
services.AddDistributedMemoryCache();
break;
case DistributedCacheType.SqlServer:
services.AddDistributedSqlServerCache(options =>
{
options.ConnectionString = distributedCacheConfig.ConnectionString;
options.SchemaName = distributedCacheConfig.SchemaName;
options.TableName = distributedCacheConfig.TableName;
});
break;
case DistributedCacheType.Redis:
services.AddStackExchangeRedisCache(options =>
{
options.Configuration = distributedCacheConfig.ConnectionString;
options.InstanceName = distributedCacheConfig.InstanceName ?? string.Empty;
});
break;
case DistributedCacheType.RedisSynchronizedMemory:
services.AddStackExchangeRedisCache(options =>
{
options.Configuration = distributedCacheConfig.ConnectionString;
options.InstanceName = distributedCacheConfig.InstanceName ?? string.Empty;
});
break;
}
}
///
/// Adds data protection services
///
/// Collection of service descriptors
public static void AddNopDataProtection(this IServiceCollection services)
{
var appSettings = Singleton.Instance;
if (appSettings.Get().Enabled && appSettings.Get().StoreDataProtectionKeys)
{
var blobServiceClient = new BlobServiceClient(appSettings.Get().ConnectionString);
var blobContainerClient = blobServiceClient.GetBlobContainerClient(appSettings.Get().DataProtectionKeysContainerName);
var blobClient = blobContainerClient.GetBlobClient(NopDataProtectionDefaults.AzureDataProtectionKeyFile);
var dataProtectionBuilder = services.AddDataProtection().PersistKeysToAzureBlobStorage(blobClient);
if (!appSettings.Get().DataProtectionKeysEncryptWithVault)
return;
var keyIdentifier = appSettings.Get().DataProtectionKeysVaultId;
var credentialOptions = new DefaultAzureCredentialOptions();
var tokenCredential = new DefaultAzureCredential(credentialOptions);
dataProtectionBuilder.ProtectKeysWithAzureKeyVault(new Uri(keyIdentifier), tokenCredential);
}
else
{
var dataProtectionKeysPath = CommonHelper.DefaultFileProvider.MapPath(NopDataProtectionDefaults.DataProtectionKeysPath);
var dataProtectionKeysFolder = new System.IO.DirectoryInfo(dataProtectionKeysPath);
//configure the data protection system to persist keys to the specified directory
services.AddDataProtection().PersistKeysToFileSystem(dataProtectionKeysFolder);
}
}
///
/// Adds authentication service
///
/// Collection of service descriptors
public static void AddNopAuthentication(this IServiceCollection services)
{
//set default authentication schemes
var authenticationBuilder = services.AddAuthentication(options =>
{
options.DefaultChallengeScheme = NopAuthenticationDefaults.AuthenticationScheme;
options.DefaultScheme = NopAuthenticationDefaults.AuthenticationScheme;
options.DefaultSignInScheme = NopAuthenticationDefaults.ExternalAuthenticationScheme;
});
//add main cookie authentication
authenticationBuilder.AddCookie(NopAuthenticationDefaults.AuthenticationScheme, options =>
{
options.Cookie.Name = $"{NopCookieDefaults.Prefix}{NopCookieDefaults.AuthenticationCookie}";
options.Cookie.HttpOnly = true;
options.Cookie.SecurePolicy = CookieSecurePolicy.SameAsRequest;
options.LoginPath = NopAuthenticationDefaults.LoginPath;
options.AccessDeniedPath = NopAuthenticationDefaults.AccessDeniedPath;
});
//add external authentication
authenticationBuilder.AddCookie(NopAuthenticationDefaults.ExternalAuthenticationScheme, options =>
{
options.Cookie.Name = $"{NopCookieDefaults.Prefix}{NopCookieDefaults.ExternalAuthenticationCookie}";
options.Cookie.HttpOnly = true;
options.Cookie.SecurePolicy = CookieSecurePolicy.SameAsRequest;
options.LoginPath = NopAuthenticationDefaults.LoginPath;
options.AccessDeniedPath = NopAuthenticationDefaults.AccessDeniedPath;
});
//register and configure external authentication plugins now
var typeFinder = Singleton.Instance;
var externalAuthConfigurations = typeFinder.FindClassesOfType();
var externalAuthInstances = externalAuthConfigurations
.Select(x => (IExternalAuthenticationRegistrar)Activator.CreateInstance(x));
foreach (var instance in externalAuthInstances)
instance.Configure(authenticationBuilder);
}
///
/// Add and configure MVC for the application
///
/// Collection of service descriptors
/// A builder for configuring MVC services
public static IMvcBuilder AddNopMvc(this IServiceCollection services)
{
//add basic MVC feature
var mvcBuilder = services.AddControllersWithViews();
mvcBuilder.AddRazorRuntimeCompilation();
var appSettings = Singleton.Instance;
if (appSettings.Get().UseSessionStateTempDataProvider)
{
//use session-based temp data provider
mvcBuilder.AddSessionStateTempDataProvider();
}
else
{
//use cookie-based temp data provider
mvcBuilder.AddCookieTempDataProvider(options =>
{
options.Cookie.Name = $"{NopCookieDefaults.Prefix}{NopCookieDefaults.TempDataCookie}";
options.Cookie.SecurePolicy = CookieSecurePolicy.SameAsRequest;
});
}
services.AddRazorPages();
//MVC now serializes JSON with camel case names by default, use this code to avoid it
mvcBuilder.AddNewtonsoftJson(options => options.SerializerSettings.ContractResolver = new DefaultContractResolver());
//set some options
mvcBuilder.AddMvcOptions(options =>
{
options.ModelBinderProviders.Insert(1, new NopModelBinderProvider());
//add custom display metadata provider
options.ModelMetadataDetailsProviders.Add(new NopMetadataProvider());
//in .NET model binding for a non-nullable property may fail with an error message "The value '' is invalid"
//here we set the locale name as the message, we'll replace it with the actual one later when not-null validation failed
options.ModelBindingMessageProvider.SetValueMustNotBeNullAccessor(_ => NopValidationDefaults.NotNullValidationLocaleName);
});
//add fluent validation
services.AddFluentValidationAutoValidation().AddFluentValidationClientsideAdapters();
//register all available validators from Nop assemblies
var assemblies = mvcBuilder.PartManager.ApplicationParts
.OfType()
.Where(part => part.Name.StartsWith("Nop", StringComparison.InvariantCultureIgnoreCase))
.Select(part => part.Assembly);
services.AddValidatorsFromAssemblies(assemblies);
//register controllers as services, it'll allow to override them
mvcBuilder.AddControllersAsServices();
return mvcBuilder;
}
///
/// Register custom RedirectResultExecutor
///
/// Collection of service descriptors
public static void AddNopRedirectResultExecutor(this IServiceCollection services)
{
//we use custom redirect executor as a workaround to allow using non-ASCII characters in redirect URLs
services.AddScoped, NopRedirectResultExecutor>();
}
///
/// Add and configure WebMarkupMin service
///
/// Collection of service descriptors
public static void AddNopWebMarkupMin(this IServiceCollection services)
{
//check whether database is installed
if (!DataSettingsManager.IsDatabaseInstalled())
return;
services
.AddWebMarkupMin(options =>
{
options.AllowMinificationInDevelopmentEnvironment = true;
options.AllowCompressionInDevelopmentEnvironment = true;
options.DisableMinification = !EngineContext.Current.Resolve().EnableHtmlMinification;
options.DisableCompression = true;
options.DisablePoweredByHttpHeaders = true;
})
.AddHtmlMinification(options =>
{
options.MinificationSettings.AttributeQuotesRemovalMode = HtmlAttributeQuotesRemovalMode.KeepQuotes;
options.CssMinifierFactory = new NUglifyCssMinifierFactory();
options.JsMinifierFactory = new NUglifyJsMinifierFactory();
})
.AddXmlMinification(options =>
{
var settings = options.MinificationSettings;
settings.RenderEmptyTagsWithSpace = true;
settings.CollapseTagsWithoutContent = true;
});
}
///
/// Adds WebOptimizer to the specified and enables CSS and JavaScript minification.
///
/// Collection of service descriptors
public static void AddNopWebOptimizer(this IServiceCollection services)
{
var appSettings = Singleton.Instance;
var woConfig = appSettings.Get();
if (!woConfig.EnableCssBundling && !woConfig.EnableJavaScriptBundling)
{
services.AddScoped();
return;
}
//add minification & bundling
var cssSettings = new CssBundlingSettings
{
FingerprintUrls = false,
Minify = woConfig.EnableCssBundling
};
var codeSettings = new CodeBundlingSettings
{
Minify = woConfig.EnableJavaScriptBundling,
AdjustRelativePaths = false //disable this feature because it breaks function names that have "Url(" at the end
};
services.AddWebOptimizer(null, cssSettings, codeSettings);
services.AddScoped();
}
///
/// Add and configure default HTTP clients
///
/// Collection of service descriptors
public static void AddNopHttpClients(this IServiceCollection services)
{
//default client
services.AddHttpClient(NopHttpDefaults.DefaultHttpClient).WithProxy();
//client to request current store
services.AddHttpClient();
//client to request nopCommerce official site
services.AddHttpClient().WithProxy();
//client to request reCAPTCHA service
services.AddHttpClient().WithProxy();
}
}