[fix]修正HyperLogLog.Merge对Key前缀的支持
大石头 编写于 2024-08-27 11:23:32 大石头 提交于 2024-08-27 13:25:21
NewLife.Redis
using Microsoft.Extensions.DependencyInjection.Extensions;
using Microsoft.Extensions.Options;

using NewLife;
using NewLife.Caching;
using NewLife.Caching.Services;
using NewLife.Log;

namespace Microsoft.Extensions.DependencyInjection;

/// <summary>
/// DependencyInjectionExtensions
/// </summary>
public static class DependencyInjectionExtensions
{
    /// <summary>
    /// Adds services for FullRedis to the specified Microsoft.Extensions.DependencyInjection.IServiceCollection.
    /// </summary>
    /// <param name="services"></param>
    /// <param name="config"></param>
    /// <returns></returns>
    public static FullRedis AddRedis(this IServiceCollection services, String config)
    {
        if (String.IsNullOrEmpty(config)) throw new ArgumentNullException(nameof(config));

        var redis = new FullRedis();
        redis.Init(config);

        services.TryAddSingleton<ICache>(sp =>
        {
            if (redis.Tracer is null) { redis.Tracer = sp.GetService<ITracer>(); }
            return redis;
        });
        services.AddSingleton<Redis>(sp =>
        {
            if (redis.Tracer is null) { redis.Tracer = sp.GetService<ITracer>(); }
            return redis;
        });
        services.AddSingleton(sp =>
        {
            if (redis.Tracer is null) { redis.Tracer = sp.GetService<ITracer>(); }
            return redis;
        });

        return redis;
    }

    /// <summary>
    /// Adds services for FullRedis to the specified Microsoft.Extensions.DependencyInjection.IServiceCollection.
    /// </summary>
    /// <param name="services"></param>
    /// <param name="name"></param>
    /// <param name="config"></param>
    /// <param name="timeout"></param>
    /// <returns></returns>
    public static FullRedis AddRedis(this IServiceCollection services, String name, String config, Int32 timeout = 0)
    {
        if (String.IsNullOrEmpty(config)) throw new ArgumentNullException(nameof(config));

        var redis = new FullRedis();
        if (!name.IsNullOrEmpty()) redis.Name = name;
        redis.Init(config);
        if (timeout > 0) redis.Timeout = timeout;

        services.TryAddSingleton<ICache>(sp =>
        {
            if (redis.Tracer is null) { redis.Tracer = sp.GetService<ITracer>(); }
            return redis;
        });
        services.AddSingleton<Redis>(sp =>
        {
            if (redis.Tracer is null) { redis.Tracer = sp.GetService<ITracer>(); }
            return redis;
        });
        services.AddSingleton(sp =>
        {
            if (redis.Tracer is null) { redis.Tracer = sp.GetService<ITracer>(); }
            return redis;
        });

        return redis;
    }

    /// <summary>
    /// Adds services for FullRedis to the specified Microsoft.Extensions.DependencyInjection.IServiceCollection.
    /// </summary>
    /// <param name="services"></param>
    /// <param name="server"></param>
    /// <param name="psssword"></param>
    /// <param name="db"></param>
    /// <param name="timeout"></param>
    /// <returns></returns>
    public static FullRedis AddRedis(this IServiceCollection services, String server, String psssword, Int32 db, Int32 timeout = 0)
    {
        if (String.IsNullOrEmpty(server)) throw new ArgumentNullException(nameof(server));

        var redis = new FullRedis(server, psssword, db);
        if (timeout > 0) redis.Timeout = timeout;

        services.TryAddSingleton<ICache>(sp =>
        {
            if (redis.Tracer is null) { redis.Tracer = sp.GetService<ITracer>(); }
            return redis;
        });
        services.AddSingleton<Redis>(sp =>
        {
            if (redis.Tracer is null) { redis.Tracer = sp.GetService<ITracer>(); }
            return redis;
        });
        services.AddSingleton(sp =>
        {
            if (redis.Tracer is null) { redis.Tracer = sp.GetService<ITracer>(); }
            return redis;
        });

        return redis;
    }

    /// <summary>添加Redis缓存</summary>
    /// <param name="services"></param>
    /// <param name="setupAction"></param>
    /// <returns></returns>
    /// <exception cref="ArgumentNullException"></exception>
    public static IServiceCollection AddRedis(this IServiceCollection services, Action<RedisOptions> setupAction)
    {
        if (services == null)
            throw new ArgumentNullException(nameof(services));
        if (setupAction == null)
            throw new ArgumentNullException(nameof(setupAction));

        services.AddOptions();
        services.Configure(setupAction);
        //services.Add(ServiceDescriptor.Singleton<ICache, FullRedis>());
        services.AddSingleton(sp => new FullRedis(sp, sp.GetRequiredService<IOptions<RedisOptions>>().Value));

        return services;
    }

    /// <summary>
    /// 添加键前缀的PrefixedRedis缓存
    /// </summary>
    /// <param name="services"></param>
    /// <param name="setupAction"></param>
    /// <returns></returns>
    /// <exception cref="ArgumentNullException"></exception>
    public static IServiceCollection AddPrefixedRedis(this IServiceCollection services, Action<RedisOptions> setupAction)
    {
        if (services == null)
            throw new ArgumentNullException(nameof(services));
        if (setupAction == null)
            throw new ArgumentNullException(nameof(setupAction));

        services.AddOptions();
        services.Configure(setupAction);
        services.AddSingleton(sp => new PrefixedRedis(sp, sp.GetRequiredService<IOptions<RedisOptions>>().Value));

        return services;
    }

    /// <summary>添加Redis缓存提供者ICacheProvider</summary>
    /// <param name="services"></param>
    /// <returns></returns>
    public static IServiceCollection AddRedisCacheProvider(this IServiceCollection services)
    {
        services.AddSingleton<ICacheProvider, RedisCacheProvider>();

        return services;
    }
}