网站首页 网站源码
website
站点相关全部源代码,隐藏了一些关于服务器的信息
using System.Threading;
using AngleSharp.Dom;
using Dpz.Core.Infrastructure.Entity;
using EasyCaching.Serialization.SystemTextJson.Configurations;
using Medallion.Threading;
using Medallion.Threading.Redis;
using Microsoft.Extensions.DependencyInjection;
using StackExchange.Redis;

namespace Dpz.Core.Service;

public static class ServiceExtensions
{
    /// <summary>
    /// 根据当前页索引pageIndex及每页记录数pageSize获取要分页的ViewModel数据对象。
    /// </summary>
    /// <typeparam name="TSource">原类型</typeparam>
    /// <typeparam name="TDestination">目标类型</typeparam>
    /// <param name="source">包含所有要分页数据的IMongoQueryable对象。</param>
    /// <param name="pageIndex">当前页索引。</param>
    /// <param name="pageSize">每页显示的记录数。</param>
    /// <returns></returns>
    public static IPagedList<TDestination> ToPagedList<TSource, TDestination>(this IMongoQueryable<TSource> source,
        int pageIndex, int pageSize) where TDestination : IMapFrom<TSource>, IHaveCustomMapping, new()
    {
        if (pageIndex < 1)
            pageIndex = 1;
        var itemIndex = (pageIndex - 1) * pageSize;
        var totalItemCount = source.Count();
        while (totalItemCount <= itemIndex && pageIndex > 1)
        {
            itemIndex = (--pageIndex - 1) * pageSize;
        }

        var pageOfItems = source.Skip(itemIndex).Take(pageSize);
        var data = ServiceMapper.GetInstance().Mapper.Map<List<TDestination>>(pageOfItems.ToList());
        return new PagedList<TDestination>(data, pageIndex, pageSize, totalItemCount);
    }

    /// <summary>
    /// 根据当前页索引pageIndex及每页记录数pageSize获取要分页的ViewModel数据对象。
    /// </summary>
    /// <typeparam name="TSource">原类型</typeparam>
    /// <typeparam name="TDestination">目标类型</typeparam>
    /// <param name="source">包含所有要分页数据的IMongoQueryable对象。</param>
    /// <param name="pageIndex">当前页索引。</param>
    /// <param name="pageSize">每页显示的记录数。</param>
    /// <returns></returns>
    public static async Task<IPagedList<TDestination>> ToPagedListAsync<TSource, TDestination>(
        this IMongoQueryable<TSource> source, int pageIndex, int pageSize)
        where TDestination : IMapFrom<TSource>, new()
    {
        if (pageIndex < 1)
            pageIndex = 1;
        var itemIndex = (pageIndex - 1) * pageSize;
        var totalItemCount = source.Count();
        while (totalItemCount <= itemIndex && pageIndex > 1)
        {
            itemIndex = (--pageIndex - 1) * pageSize;
        }

        var pageOfItems = source.Skip(itemIndex).Take(pageSize);
        var data = ServiceMapper.GetInstance().Mapper.Map<List<TDestination>>(await pageOfItems.ToListAsync());
        return new PagedList<TDestination>(data, pageIndex, pageSize, totalItemCount);
    }

    public static async Task<IPagedList<TDestination>> ToPagedListAsync<TSource, TDestination>(
        this IMongoQueryable<TSource> source, int pageIndex, int pageSize, Func<TSource, TDestination> func)
        where TSource : IBaseEntity, new()
        where TDestination : new()
    {
        if (pageIndex < 1)
            pageIndex = 1;
        var itemIndex = (pageIndex - 1) * pageSize;
        var totalItemCount = source.Count();
        while (totalItemCount <= itemIndex && pageIndex > 1)
        {
            itemIndex = (--pageIndex - 1) * pageSize;
        }

        var pageOfItems = source.Skip(itemIndex).Take(pageSize);
        var data = await pageOfItems.ToListAsync();
        return new PagedList<TDestination>(data.Select(func), pageIndex, pageSize, totalItemCount);
    }

    public static async Task<IPagedList<TDestination>> ToPagedListAsync<TSource, TDestination>(
        this IFindFluent<TSource, TSource> source, int pageIndex, int pageSize)
        where TSource : IBaseEntity, new()
        where TDestination : new()
    {
        if (pageIndex < 1)
            pageIndex = 1;
        var itemIndex = (pageIndex - 1) * pageSize;
        var totalItemCount = checked((int)await source.CountDocumentsAsync());
        while (totalItemCount <= itemIndex && pageIndex > 1)
        {
            itemIndex = (--pageIndex - 1) * pageSize;
        }

        var pageOfItems = source.Skip(itemIndex).Limit(pageSize);
        var data = ServiceMapper.GetInstance().Mapper.Map<List<TDestination>>(await pageOfItems.ToListAsync());
        return new PagedList<TDestination>(data, pageIndex, pageSize, totalItemCount);
    }

    public static async Task<IPagedList<TViewModel>> ToPagedListByModelAsync<TEntity, TViewModel>(
        this IRepository<TEntity> repository,
        TViewModel viewModel, int pageIndex, int pageSize)
        where TEntity : IBaseEntity, new()
        where TViewModel : IMapFrom<TEntity>, new()
    {
        var expression = viewModel.GenerateExpressTree();
        var source = await repository.SearchFor(expression)
            .ToPagedListAsync<TEntity, TViewModel>(pageIndex, pageSize);
        return source;
    }

    public static async Task<IPagedList<TModel>> ToPagedListAsync<TModel>(this IMongoQueryable<TModel> source,
        int pageIndex, int pageSize)
        where TModel : IBaseEntity, new()
    {
        if (pageIndex < 1)
            pageIndex = 1;
        var itemIndex = (pageIndex - 1) * pageSize;
        var totalItemCount = source.Count();
        while (totalItemCount <= itemIndex && pageIndex > 1)
        {
            itemIndex = (--pageIndex - 1) * pageSize;
        }

        var pageOfItems = source.Skip(itemIndex).Take(pageSize);
        var data = await pageOfItems.ToListAsync();
        return new PagedList<TModel>(data, pageIndex, pageSize, totalItemCount);
    }

    /// <summary>
    /// 
    /// </summary>
    /// <param name="source"></param>
    /// <param name="pageIndex"></param>
    /// <param name="pageSize"></param>
    /// <param name="totalItem">总数</param>
    /// <typeparam name="T"></typeparam>
    /// <returns></returns>
    public static IPagedList<T> ToPagedList<T>(this IEnumerable<T> source, int pageIndex, int pageSize,
        int totalItem)
    {
        return new PagedList<T>(source, pageIndex, pageSize, totalItem);
    }


    /// <summary>
    /// 获取img标签图片地址
    /// </summary>
    /// <param name="elements"></param>
    /// <returns></returns>
    public static List<string> GetElementsImageUrls(this IHtmlCollection<IElement> elements)
    {
        return elements.Select(x => x.Attributes["src"])
            .Where(x => x != null)
            .Select(x => x!.Value)
            .Where(x => x.Any())
            .ToList();
    }

    /// <summary>
    /// Mapper to TDestination
    /// </summary>
    /// <param name="source"></param>
    /// <typeparam name="TSource"></typeparam>
    /// <typeparam name="TDestination"></typeparam>
    /// <returns></returns>
    public static async Task<IList<TDestination>> ToListAsync<TSource, TDestination>(
        this IMongoQueryable<TSource> source)
        where TSource : IBaseEntity, new()
        where TDestination : IMapFrom<TSource>, new()
    {
        var data = await source.ToListAsync();
        return ServiceMapper.GetInstance().Mapper.Map<List<TDestination>>(data);
    }

    public const string ServiceCacheProviderName = "hybrid-cache";

    public static void AddBusinessServices(this IServiceCollection services,IConfiguration configuration)
    {
        services.AddTransient<IUnitOfWork,UnitOfWork>();
        services.AddScoped(typeof(IRepository<>),typeof(Repository<>));

#if DEBUG
        services.AddScoped<Func<IRepository<Music>>>(x =>
        {
            var config = x.GetService<IConfiguration>();
            var connectionString = config?.GetConnectionString("mongodb-test");
            return () => new Repository<Music>(connectionString);
        });
#endif
        
        services.AddSingleton<IMapper>(_ => ServiceMapper.Instance.Mapper);
        
        const string cacheName = "redis";
        const string memoryCacheName = "dpangzi-memory";
        const string serializerName = "dpangzi-message-pack";
        var redisConnectionStr = configuration.GetConnectionString(cacheName) ?? "";
        services.AddEasyCaching(options =>
        {
            options.UseInMemory(memoryCacheName);
            options
                .UseRedis(config =>
                {
                    config.DBConfig.Configuration = redisConnectionStr;
                    config.DBConfig.Database = 2;
                }, cacheName)
                .WithMessagePack(cacheName);
            options.UseHybrid(config =>
                {
                    config.TopicName = "service-cache";
                    config.EnableLogging = true;
                    config.LocalCacheProviderName = memoryCacheName;
                    config.DistributedCacheProviderName = cacheName;
                }, ServiceCacheProviderName)
                .WithRedisBus(config =>
                {
                    config.Configuration = redisConnectionStr;
                    config.Database = 3;
                    config.SerializerName = serializerName;
                })
                .WithMessagePack(serializerName);
        });
        
        // 分布式锁
        services.AddSingleton<IDistributedLockProvider>(_ =>
        {
            var connectionMultiplexer = ConnectionMultiplexer.Connect(redisConnectionStr);
            var database = connectionMultiplexer.GetDatabase();
            return new RedisDistributedSynchronizationProvider(database);
        });
    }
}
loading