为了能够通过配置文件(appsettings.json)或通过代码进行背景图片与模板进行配置、可自定义资源类型、自定义验证规则,本节创建一些扩展类,用来实现这些功能。
上一节内容:NET 6 实现滑动验证码(三)、接口
扩展类都放在了Extensions文件夹下
目录- CaptchaBuilderExtensions.cs
- CaptchaServiceCollectionExtensions.cs
- ServiceCollectionExtensions.cs
- SlideCaptchaException.cs
CaptchaBuilderExtensions.cs
CaptchaBuilderExtensions.cs实现了自定义提供验证码背景图片资源或模板资源、自定义实现资源类型、替换默认验证规则、禁用默认凹槽模板
using SlideCaptcha;
using SlideCaptcha.Interface;
using SlideCaptcha.Resources.Provider;
using System.Linq;
namespace Microsoft.Extensions.DependencyInjection
{
public static class CaptchaBuilderExtensions
{
/// <summary>
/// 自定义提供验证码背景图片资源或模板资源
/// </summary>
/// <typeparam name="TProvider">自定义实现</typeparam>
/// <param name="builder"></param>
/// <returns></returns>
public static CaptchaBuilder AddResourceProvider<TProvider>(this CaptchaBuilder builder) where TProvider : class, IResourceProvider
{
builder.Services.AddSingleton<IResourceProvider, TProvider>();
return builder;
}
/// <summary>
/// 自定义实现资源类型
/// </summary>
/// <typeparam name="THandler">自定义实现</typeparam>
/// <param name="builder"></param>
/// <returns></returns>
public static CaptchaBuilder AddResourceHandler<THandler>(this CaptchaBuilder builder) where THandler : class, IResourceHandler
{
builder.Services.AddSingleton<IResourceHandler, THandler>();
return builder;
}
/// <summary>
/// 替换默认的验证规则
/// </summary>
/// <typeparam name="TValidator">自定义验证规则</typeparam>
/// <param name="builder"></param>
/// <returns></returns>
public static CaptchaBuilder ReplaceValidator<TValidator>(this CaptchaBuilder builder) where TValidator : class, IValidator
{
builder.Services.Replace<IValidator, TValidator>();
return builder;
}
/// <summary>
/// 禁用默认凹槽模板
/// </summary>
/// <param name="builder"></param>
/// <returns></returns>
public static CaptchaBuilder DisableDefaultTemplates(this CaptchaBuilder builder)
{
var serviceDescriptor = builder.Services.FirstOrDefault(e => e.ImplementationType == typeof(EmbeddedResourceProvider));
if (serviceDescriptor != null)
{
builder.Services.Remove(serviceDescriptor);
}
return builder;
}
}
}
CaptchaServiceCollectionExtensions.cs
CaptchaServiceCollectionExtensions.cs为自动注入必要的接口
using Microsoft.Extensions.Configuration;
using SlideCaptcha;
using SlideCaptcha.Constant;
using SlideCaptcha.Generator;
using SlideCaptcha.Interface;
using SlideCaptcha.Resources;
using SlideCaptcha.Resources.Handler;
using SlideCaptcha.Resources.Provider;
using SlideCaptcha.Storage;
using SlideCaptcha.Validator;
using System;
namespace Microsoft.Extensions.DependencyInjection
{
public static class CaptchaServiceCollectionExtensions
{
/// <summary>
/// 依赖注入必要的接口。
/// </summary>
/// <param name="services"></param>
/// <param name="configuration"></param>
/// <param name="optionsAction"></param>
/// <returns></returns>
public static CaptchaBuilder AddSlideCaptcha(this IServiceCollection services, IConfiguration configuration, Action<CaptchaOptions> optionsAction = default)
{
services.Configure<CaptchaOptions>(configuration?.GetSection("SlideCaptcha"));
//对所需验证的参数进行检查,如果参数不合法就抛一个异常出来
if (optionsAction != null) services.PostConfigure(optionsAction);
var builder = new CaptchaBuilder(services);
services.AddSingleton<IResourceProvider, OptionsResourceProvider>();
services.AddSingleton<IResourceProvider, EmbeddedResourceProvider>();
services.AddSingleton<IResourceHandlerManager, CachedResourceHandlerManager>();
services.AddSingleton<IResourceManager, DefaultResourceManager>();
services.AddSingleton<ISliderCaptchaImageGenerator, SliderCaptchaImageGenerator>();
services.AddSingleton<IResourceHandler, FileResourceHandler>();
services.AddSingleton<IResourceHandler, EmbeddedResourceHandler>();
services.AddScoped<ICaptcha, ImageCaptcha>();
services.AddScoped<IStorage, DefaultStorage>();
services.AddScoped<IValidator, SimpleValidator>();
return builder;
}
}
}
ServiceCollectionExtensions.cs
ServiceCollectionExtensions.cs用于实现IServiceCollection的Replace方法
using System;
using System.Collections.Generic;
using System.Linq;
namespace Microsoft.Extensions.DependencyInjection
{
public static class ServiceCollectionExtensions
{
public static IServiceCollection Replace<TService, TImplementation>(this IServiceCollection services)
where TImplementation : TService
{
return services.Replace<TService>(typeof(TImplementation));
}
public static IServiceCollection Replace<TService>(this IServiceCollection services, Type implementationType)
{
return services.Replace(typeof(TService), implementationType);
}
public static IServiceCollection Replace(this IServiceCollection services, Type serviceType, Type implementationType)
{
if (services == null)
{
throw new ArgumentNullException(nameof(services));
}
if (serviceType == null)
{
throw new ArgumentNullException(nameof(serviceType));
}
if (implementationType == null)
{
throw new ArgumentNullException(nameof(implementationType));
}
if (!services.TryGetDescriptors(serviceType, out var descriptors))
{
throw new ArgumentException($"No services found for {serviceType.FullName}.", nameof(serviceType));
}
foreach (var descriptor in descriptors)
{
var index = services.IndexOf(descriptor);
services.Insert(index, descriptor.WithImplementationType(implementationType));
services.Remove(descriptor);
}
return services;
}
private static bool TryGetDescriptors(this IServiceCollection services, Type serviceType, out ICollection<ServiceDescriptor> descriptors)
{
return (descriptors = services.Where(service => service.ServiceType == serviceType).ToArray()).Any();
}
private static ServiceDescriptor WithImplementationType(this ServiceDescriptor descriptor, Type implementationType)
{
return new ServiceDescriptor(descriptor.ServiceType, implementationType, descriptor.Lifetime);
}
}
}
SlideCaptchaException.cs
SlideCaptchaException.cs 实现自定义异常信息。
using System;
namespace SlideCaptcha.Exceptions
{
public class SlideCaptchaException : Exception
{
public SlideCaptchaException() : base()
{
}
public SlideCaptchaException(string message) : base(message)
{
}
public SlideCaptchaException(string message, Exception innerException) : base(message, innerException)
{
}
}
}
欢迎大家关注我的微信公众号,一起进步,一起成长下载方式:
扫描公众号二维码,或搜索公众号fenxiang3389关注我,回复captcha
下载,压缩包包含了验证码类库、服务端API、HTML+JQuery完整代码、vue3组件代码及演示代码!
![](/i/l/?n=23&i=blog/93324/202212/93324-20221205182127693-712634750.png)