<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      webapi開發(fā)框架實踐

      項目鏈接以及目錄結構

      liuzhixin405/efcore-template (github.com)

      這是一個純webapi的開發(fā)框架。

      1、支持的orm有efcore6、dapper,可以靈活切換數(shù)據(jù)庫。

      using Microsoft.CodeAnalysis.CSharp.Syntax;
      using Microsoft.CodeAnalysis.Elfie.Model;
      using Microsoft.EntityFrameworkCore;
      using project.Context;
      using project.Repositories;
      using project.Services;
      using RepositoryComponent.DbFactories;
      
      namespace project.Extensions
      {
          public static partial class TheExtensions
          {
              public static void AddDatabase(this WebApplicationBuilder builder)
              {
                  ///sqlserver   
                  if (builder.Configuration["DbType"]?.ToLower() == "sqlserver")
                  {
                      builder.Services.AddDbContext<ReadProductDbContext>(options => options.UseSqlServer(builder.Configuration["ConnectionStrings:SqlServer:ReadConnection"]), ServiceLifetime.Scoped);
                      builder.Services.AddDbContext<WriteProductDbContext>(options => options.UseSqlServer(builder.Configuration["ConnectionStrings:SqlServer:WriteConnection"]), ServiceLifetime.Scoped);
      
                  }
                  ///mysql
                  else if (builder.Configuration["DbType"]?.ToLower() == "mysql")
                  {
                      builder.Services.AddDbContext<ReadProductDbContext>(options => options.UseMySQL(builder.Configuration["ConnectionStrings:MySql:ReadConnection"]), ServiceLifetime.Scoped);
                      builder.Services.AddDbContext<WriteProductDbContext>(options => options.UseMySQL(builder.Configuration["ConnectionStrings:MySql:WriteConnection"]), ServiceLifetime.Scoped);
      
                  }
                  else
                  {
                      //throw new ArgumentNullException("δ???????????????");
                      builder.Services.AddDbContext<ReadProductDbContext>(options => options.UseInMemoryDatabase("test_inmemory_db"), ServiceLifetime.Scoped);
                      builder.Services.AddDbContext<WriteProductDbContext>(options => options.UseInMemoryDatabase("test_inmemory_db"), ServiceLifetime.Scoped);
      
                  }
      
                  builder.Services.AddScoped<Func<ReadProductDbContext>>(provider => () => provider.GetService<ReadProductDbContext>() ?? throw new ArgumentNullException("ReadProductDbContext is not inject to program"));
                  builder.Services.AddScoped<Func<WriteProductDbContext>>(provider => () => provider.GetService<WriteProductDbContext>() ?? throw new ArgumentNullException("WriteProductDbContext is not inject to program"));
      
                  builder.Services.AddScoped<DbFactory<WriteProductDbContext>>();
                  builder.Services.AddScoped<DbFactory<ReadProductDbContext>>();
      
                  builder.Services.AddTransient<IReadProductRepository, ProductReadRepository>();
                  builder.Services.AddTransient<IWriteProductRepository, ProductWriteRepository>();
                  builder.Services.AddTransient<IProductService, ProductService>();
      
                  builder.Services.AddTransient<ICustomerService, CustomerService>();
              }
          }
      }

      2、至于消息中間件有rabbitmq、kafka,也是通過配置文件來指定哪一個實現(xiàn)。

      using MessageMiddleware.Factory;
      using MessageMiddleware.RabbitMQ;
      
      namespace project.Extensions
      {
          public static partial class TheExtensions
          {
              public static void AddMq(this WebApplicationBuilder builder)
              {
                  var rabbitMqSetting = new RabbitMQSetting
                  {
                      ConnectionString = builder.Configuration["MqSetting:RabbitMq:ConnectionString"].Split(';'),
                      Password = builder.Configuration["MqSetting:RabbitMq:PassWord"],
                      Port = int.Parse(builder.Configuration["MqSetting:RabbitMq:Port"]),
                      SslEnabled = bool.Parse(builder.Configuration["MqSetting:RabbitMq:SslEnabled"]),
                      UserName = builder.Configuration["MqSetting:RabbitMq:UserName"],
                  };
                  var kafkaSetting = new MessageMiddleware.Kafka.Producers.ProducerOptions
                  {
                      BootstrapServers = builder.Configuration["MqSetting:Kafka:BootstrapServers"],
                      SaslUsername = builder.Configuration["MqSetting:Kafka:SaslUserName"],
                      SaslPassword = builder.Configuration["MqSetting:Kafka:SaslPassWord"],
                      Key = builder.Configuration["MqSetting:Kafka:Key"]
                  };
                  var mqConfig = new MQConfig
                  {
                      ConsumerLog = bool.Parse(builder.Configuration["MqSetting:ConsumerLog"]),
                      PublishLog = bool.Parse(builder.Configuration["MqSetting:PublishLog"]),
                      Rabbit = rabbitMqSetting,
                      Use = int.Parse(builder.Configuration["MqSetting:Use"]),
                      Kafka = kafkaSetting
                  };
                  builder.Services.AddSingleton<MQConfig>(sp => mqConfig);
                  builder.Services.AddMQ(mqConfig);
              }
          }
      }

      3、該項目還集成了mongodb和elasticsearch,在project項目中沒有寫實現(xiàn)案例,實現(xiàn)起來也很簡單。

      4、下面是分布式雪花id的實現(xiàn),先注入代碼,使用的時候直接使用distributedid即可。

       builder.Services.AddDistributedLock(x =>
       {
           x.LockType = LockType.InMemory;
           x.RedisEndPoints = new string[] { builder.Configuration["DistributedRedis:ConnectionString"] ?? throw new Exception("$未能獲取distributedredis連接字符串")};
       }).AddCache(new CacheOptions
       {
           CacheType = CacheTypes.Redis,
           RedisConnectionString = builder.Configuration["DistributedRedis:ConnectionString"] ?? throw new Exception("$未能獲取distributedredis連接字符串")
       }).AddDistributedId(new DistributedIdOptions
       {
           Distributed = true
       });
       newProduct.Id = _distributedId.NewLongId().ToString();

      5、緩存使用的是分布式緩存和內存緩存,其中分布式緩存有一般實現(xiàn)和指定序列化格式的實現(xiàn)。

      using System.Text;
      using System.Text.Json.Serialization;
      using MessagePack;
      using StackExchange.Redis.Extensions.Core;
      using StackExchange.Redis.Extensions.Core.Abstractions;
      using StackExchange.Redis.Extensions.Core.Configuration;
      using StackExchange.Redis.Extensions.Core.Implementations;
      
      namespace project.Utility.Helper
      {
          public class CacheHelper
          {
              private static IRedisClientFactory _factory_with_msgpack;
              private static IRedisDatabase _redis_with_msgpack => _factory_with_msgpack.GetDefaultRedisDatabase();
      
              private static IRedisClientFactory _factory;
              private static IRedisDatabase _redis => _factory.GetDefaultRedisDatabase();
              public static void Init(IConfiguration configuration)
              {
                  var config = configuration.GetSection("Redis").Get<RedisConfiguration>();
                  _factory = new RedisClientFactory(new[] { config }, null, new RedisSerializer());
                  _factory_with_msgpack = new RedisClientFactory(new[] { config }, null, new RedisMessagepackSerializer());
              }
              static CacheHelper() { }
      
              public static T Get<T>(string key)
              {
                  return _redis.GetAsync<T>(key).GetAwaiter().GetResult();
              }
              public static async Task<T> GetAsync<T>(string key)
              {
                  return await _redis.GetAsync<T>(key);
              }
              public static async Task<T> GetAsync_With_Msgpack<T>(string key)
              {
                  return await _redis_with_msgpack.GetAsync<T>(key);
              }
      
              public static string Get(string key)
              {
                  return _redis.GetAsync<string>(key).GetAwaiter().GetResult();
              }
      
              public static bool Set(string key, object value, TimeSpan expiresIn)
              {
                  return _redis.AddAsync(key, value, expiresIn).GetAwaiter().GetResult();
              }
              public static async Task<bool> SetAsync(string key, object value, TimeSpan expiresIn)
              {
                  return await _redis.AddAsync(key, value, expiresIn);
              }
      
              public static async Task<bool> SetAsync_With_Msgpack(string key, object value, TimeSpan expiresIn)
              {
                  return await _redis_with_msgpack.AddAsync(key, value, expiresIn);
              }
      
              /// <summary>
              /// 以秒為單位,返回給定 key 的剩余生存時間
              /// </summary>
      
              public static long GetExpirin(string key)
              {
                  var timespan = _redis.Database.KeyTimeToLive(key);
                  if (timespan == null) { return 0; }
                  return (long)timespan.Value.TotalSeconds;
              }
              public static bool KeyExpire(string key, TimeSpan expiresIn)
              {
                  return _redis.Database.KeyExpire(key, expiresIn);
              }
              public static async Task<bool> RemoveKeyAsync(string key)
              {
                  return await _redis.Database.KeyDeleteAsync(key);
              }
              public static long RemoveKey(string key)
              {
                  var result = _redis.Database.KeyDelete(key);
                  return result ? 1 : 0;
              }
          }
      
      
          public class RedisSerializer : ISerializer
          {
              public T? Deserialize<T>(byte[] serializedObject)
              {
                  var data = Encoding.UTF8.GetString(serializedObject);
                  return System.Text.Json.JsonSerializer.Deserialize<T>(data);
              }
      
              public byte[] Serialize<T>(T? item)
              {
                  var data = System.Text.Json.JsonSerializer.Serialize(item);
                  return Encoding.UTF8.GetBytes(data);
              }
          }
      
          public class RedisMessagepackSerializer : ISerializer
          {
              private MessagePackSerializerOptions _options;
              public RedisMessagepackSerializer()
              {
                  _options = MessagePackSerializerOptions.Standard.WithCompression(MessagePackCompression.Lz4BlockArray);
              }
              public T? Deserialize<T>(byte[] serializedObject)
              {
                  return MessagePackSerializer.Deserialize<T>(serializedObject, _options);
              }
      
              public byte[] Serialize<T>(T? item)
              {
                  return MessagePackSerializer.Serialize(item, _options);
              }
          }
      }

      6、單元測試、集成測試沒有寫。

      更細節(jié)的需要自己看代碼,這應該是一個基本的開發(fā)具備的功能。

      該項目下載下來可以直接運行。

      posted @ 2023-09-12 14:44  星仔007  閱讀(864)  評論(0)    收藏  舉報
      主站蜘蛛池模板: 无码粉嫩虎白一线天在线观看| 精品国产免费一区二区三区香蕉| 色欲久久久天天天综合网| 国产日韩精品中文字幕| 亚洲老熟女一区二区三区 | 中文字幕av无码免费一区| 高清无码爆乳潮喷在线观看| 成人午夜视频一区二区无码| 亚洲国产成人av国产自| 人妻中文字幕不卡精品| 99精品国产在热久久婷婷| 国产中年熟女高潮大集合| 国产精品黑色丝袜在线观看 | 性一交一乱一乱一视频| 国产欧亚州美日韩综合区| 人妻夜夜爽天天爽三区丁香花| 四虎成人精品永久网站| 99精品国产一区二区三| 久久久久国产精品熟女影院| 欧美亚洲一区二区三区在线| 天堂网亚洲综合在线| 国产女人高潮视频在线观看| 天堂www在线中文| 国产精品无码午夜福利| 国产桃色在线成免费视频| 国产av人人夜夜澡人人爽麻豆| 久久精品国产色蜜蜜麻豆| 狠狠亚洲色一日本高清色| 亚洲天堂激情av在线| 国产精品亚洲аv无码播放| 日本中文字幕久久网站| 国产精品女人毛片在线看| √天堂资源网最新版在线| 国产精品日韩av一区二区| 精品一区二区中文字幕| 国产睡熟迷奷系列网站| 国产在线一区二区不卡| 免费无码午夜福利片| 国产日产亚洲系列av| 日韩一区二区三区无码影院| 中文激情一区二区三区四区|