• net6中的一些常用组件和使用记录,不断更新…


    0. How to use iConfiguration, Environment

    Use it directly in the host after Builder.

    builder.Configuration;
    builder.Environment
    

    How to use swagger

    The .NET 6 comes with the template to add swagger to it, you can use it directly.

    builder.Services.AddSwaggerGen();
    
    if (app.Environment.IsDevelopment())
    {
        app.UseSwagger();
        app.UseSwaggerUI();
    }
    

    2. How to add EFCORE to .NET 6

    Add it according to the EFCORE usual use method, the Entity and DBCONTEXT of the applaud form, add it in the program file

    builder.Services.AddDbContext<Service.DataContext>(opt => {
        opt.UseSqlServer(builder.Configuration.GetConnectionString("Default"));
    });
    

    You can inject it in other places to use Datacontext

    Using the SQLite database, you need to reference Microsoft.EntityFrameworkCore.SQLITE,
    and changed when adding services

    opt.UseSqlite(builder.Configuration.GetConnectionString("Default"));
    

    Package Management Console Database Structure Generation Method:
    Create migration using add-migration
    Update data structure using Update-Database

    3. How to inject a service

    builder.Services.AddScoped<UserIdentyService>();
    

    4. How to define global useing references

    In the root directory, create a CS file, such as Globalusing.cs, add your global reference in it, and normal reference is different, add global in front of using

    global using Service;
    global using Entity;
    global using Entity.Dto;
    

    5. How to use Autofac

    Add NuGet reference

    Autofac.Extensions.DependencyInjection
    

    Program.cs file Add autofac use and injection configuration

    builder.Host.UseServiceProviderFactory(new AutofacServiceProviderFactory());
    builder.Host.ConfigureContainer<ContainerBuilder>(builder =>
     {
         Assembly assembly = Assembly.Load("Service.dll");
         builder.RegisterAssemblyTypes(assembly)
                //.AsimplementInterfaces() // no interface injection method
                .InstancePerDependency();
     });
    

    The function can be constructed to be used in this time.

    6. How to use Log4Net

    Add a reference

    Microsoft.Extensions.Logging.Log4Net.AspNetCore
    

    New Profile Log4Net.config;
    Add Service Configuration

    // Inject log4net
    builder.Services.AddLogging(cfg =>
    {
             // The default configuration file path is in the root directory, and the file name is log4net.config
        //cfg.AddLog4Net();
             // If the file path or name changes, you need to reset its path or name
             / / For example, create a folder called config in the root of the project, move the log4net.config file into it and renamed log4net.config
             // The following code needs to be configured.
        cfg.AddLog4Net(new Log4NetProviderOptions()
        {
            Log4NetConfigFileName = "config/log4net.config",
            Watch = true
        });
    });
    

    You can define it in a required place

    _logger = LogManager.GetLogger(typeof(UserController));
    

    7. How to use global abnormal filters

    First create a GlobalExceptionFilter global abnormal filter, inherited to exceptionFilter, used to receive an exception thrown

    public class GlobalExceptionFilter : IExceptionFilter
    {
        readonly IWebHostEnvironment hostEnvironment;
        readonly ILog logger;
        public GlobalExceptionFilter(IWebHostEnvironment _hostEnvironment)
        {
            this.hostEnvironment = _hostEnvironment;
            this.logger = LogManager.GetLogger(typeof(GlobalExceptionFilter));
        }
        public void OnException(ExceptionContext context)
        {
                     if (! context.exceptionhand // If the exception is not processed
            {
                var result = new ApiResult
                {
                    Code = 500,
                    IsSuccess = false,
                                     Message = "Unreated exception in the server"
                };
    
                if (hostEnvironment.IsDevelopment())
                {
                    result.Message += "," + context.Exception.Message;
                    result.Data = context.Exception.StackTrace;
                }
    
                logger.Error(result);
    
                context.Result = new JsonResult(result);
                             Context.exceptionHandled = true; // Abnormal processed
            }
        }
    }
    

    Then add global abnormal filter in Service

    builder.Services.AddControllers(option =>
        {
            option.Filters.Add<GlobalExceptionFilter>();
        }
    );
    

    Add a controller method to complete the test

    [HttpGet("exception")]
    public ApiResult ExceptionAction()
    {
        throw new NotImplementedException();
    }
    

    8. How to use Redis to cache

    Use stackexchange.redis as the cache component (other components similar to usage). Nuget installation stackedxchange.redis.extensions.core
    First, create a class REDISCLIENT for managing the connection and operation of REDIS, and then build a RedisClientFactory class to create Redis connection;

    public class RedisClient{...}
    public class RedisClientFactory{...}
    

    Adding Redis in Appsettings.json

    "RedisConfig": {
        "Redis_Default": {
          "Connection": "127.0.0.1:6379",
          "InstanceName": "Redis1:"
        },
        "Redis_6": {
          "Connection": "127.0.0.1:6379",
          "DefaultDatabase": 6,
          "InstanceName": "Redis2:"
        }
      }
    

    Add a REDIS client in Service

    // Add Redis's use
    builder.Services.AddSingleton<RedisClient>(_=> RedisClientFactory.GetInstance(builder.Configuration));
    

    After a single operation, you can quote the place where you want to use Redis.

    RedisClient redisClient
    ...
    this.redisDb = redisClient.GetDatabase("Redis_Default");
    redisDb.StringSet("clientId", "clientId", TimeSpan.FromSeconds(10));
    

    To use Redis to make a distributed cache, first reference Microsoft.extensions.Caching.stackexchangeRedis

    // Add the Redis distributed cache service to the service
    builder.Services.AddStackExchangeRedisCache(options =>
        {
                     // Configure configuration.getConnectionstring ("redisconnectionstring") to connect Redis.
            options.Configuration = "Redis_6";// Configuration.GetConnectionString("RedisConnectionString");
                     // redis instance name RedisDistributedcache
            options.InstanceName = "RedisDistributedCache";
        });
    

    Quoted from "Distributed Redis Cache"

    9 How to add a timed task component

    Use the Hangfire timing task components, light, sustainable, and panels.
    After reference to haangfire, you can add time to update the task.

    // Enable Hangfire service.
    builder.Services.AddHangfire(x => x.UseStorage(new MemoryStorage()));
    builder.Services.AddHangfireServer();
    
    ...
    
     // Enable Hangfire Panel
    app.UseHangfireDashboard();
     / / Open a timing task
    RecurringJob.AddOrUpdate("test",() => Console.WriteLine("Recurring!"), Cron.Minutely());
    
    

    Visithttps://localhost:7219/hangfire You can see the task panel

    10. How to use the business lock lock or pay the operation

    First of all, do this, you need to build a lock, this lock has a lock identifier Key, you can determine if the key corresponding to the key is exist according to this key.
    When a user pays or subtracts the stock, you can follow this key to first lock, and then there is a user to take the same operation when it takes other channels. It can be determined whether the operation can be continued according to whether it is locked.

    For example, a payment order, you can operate on your phone, or you can do it on your computer. This time you can lock the payment interface, as long as one payment process exists, and there is no timeout, then you cannot operate in other channels.
    We have used Redis, and use Redis to simulate this operation, specifically see the code:

    /// <summary>
             /// Test business lock
        /// </summary>
        /// <returns></returns>
        [HttpGet("lockhandle")]
        public async Task<ApiResult> LockHandle(int userId)
        {
            var key = "user";
            var token = $"ID:{userId}";
            try
            {
                if (redisDb.LockTake(key, token, TimeSpan.FromSeconds(50)))
                {
                    await Task.Delay(30 * 1000);
                                     Return AWAIT TASK.FROMROMROMROMRESULT ($ "ID: {UserID} Getting to lock, operate normally, connect.httpContext.connection.id}");
                }
                else
                {
                                     Return Await Task.FromResult (ApireSult.Fail ($ "is a lock, connect: {Request.httpContext.connection.id});
                }
            }
            catch (Exception)
            {
                throw;
            }
            finally
            {
                redisDb.LockRelease(key, token);
            }
        }
    

    11. How to configure cross-domain

    The global cross-domain is mainly recorded here, which does not include the specified API cross-domain. First add a configuration "CORS": "HTTP: 127.0.0.1: 5001", configure the URL across the domain, or you can use the default cross-domain configuration.
    Host Configure the following services, on demand:

    builder.Services.AddCors(delegate (CorsOptions options)
    {
        options.AddPolicy("CorsPolicy", delegate (CorsPolicyBuilder corsBuilder)
        {
                     / / Specify URL cross-domain
            corsBuilder.WithOrigins(builder.Configuration.GetValue<string>("Cors").Split(','));
                     // Default cross-domain
            corsBuilder.SetIsOriginAllowed((string _) => true).AllowAnyMethod().AllowAnyHeader()
                .AllowCredentials();
        });
    });
    

    12. How to use newtonsoftjson

    .NET6 default series of train is built-in System.Text.json, if there are many unfamiliar places, it must be replaced back to NewtonSoftjson, need NuGet to reference Microsoft.aspnetCore.MVC.NEWTONSOFTJSON to configure usage,
    Common configuration includes date format, case regular, loop reference configuration. . . Wait, below is a configuration

    builder.Services.AddControllers(option =>
        {
            option.Filters.Add<GlobalExceptionFilter>();
        }
    ).AddNewtonsoftJson(options =>
    {
             options.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver (); key is // hump style for serializing
        options.SerializerSettings.DateTimeZoneHandling = DateTimeZoneHandling.Local;
        options.SerializerSettings.DateFormatString = "yyyy-MM-dd HH:mm:ss";
             Options.serializersettings.referenceLoopHandling = ReferenceLoopHandling.Ignore; / / ignore the loop reference
    });  


     
     

    13. 使用kafka

    Code instance (point-to-point mode)

    copy code
       public interface IKafkaService
        {
            /// <summary>
            ///  A message to the designated topic
            /// </summary>
            /// <typeparam name="TMessage"></typeparam>
            /// <param name="topicName"></param>
            /// <param name="message"></param>
            /// <returns></returns>
            Task PublishAsync<TMessage>(string host,string topicName, TMessage message) where TMessage : class;
    
    
            /// <summary>
            ///  Subscribe from the specified topic
            /// </summary>
            /// <typeparam name="TMessage"></typeparam>
            /// <param name="topics"></param>
            /// <param name="messageFunc"></param>
            /// <param name="cancellationToken"></param>
            /// <returns></returns>
            Task SubscribeAsync<TMessage>(IEnumerable<string> topics,Action<TMessage> messageFunc,CancellationToken cancellationToken) where TMessage : class;
        }
    copy code

    // Package

    copy code
    public class KafkaService : IKafkaService
        {
            public readonly string host = "120.79.77.91:9092";
            public async Task PublishAsync<TMessage>(string host, string topicName, TMessage message) where TMessage : class
            {
                var config = new ProducerConfig
                {
                    BootstrapServers = host
                };
                using var producer = new ProducerBuilder<string, string>(config).Build();
                var data = new Message<string, string> { Key = Guid.NewGuid().ToString(), Value = Newtonsoft.Json.JsonConvert.SerializeObject(message) };
                await producer.ProduceAsync(topicName, data);
            }
    
            public async Task SubscribeAsync<TMessage>(IEnumerable<string> topics, Action<TMessage> messageFunc, CancellationToken cancellationToken) where TMessage : class
            {
                var config = new ConsumerConfig
                {
                    BootstrapServers = host,
                    GroupId = "consumer",
                    EnableAutoCommit = false,
                    StatisticsIntervalMs = 5000,
                    SessionTimeoutMs = 6000,
                    AutoOffsetReset = AutoOffsetReset.Earliest,
                    EnablePartitionEof = true
                };
                //const int commitPeriod = 5;
                using var consumer = new ConsumerBuilder<Ignore, string>(config)
                 .SetErrorHandler((_, e) =>
                 {
                     Console.WriteLine($"Error: {e.Reason}");
                 })
                 .SetStatisticsHandler((_, json) =>
                 {
                     Console.WriteLine($"  - {datetime.now:yyyy-mm-dd hh: mm: ss}> message listening..");
                 })
                 .SetPartitionsAssignedHandler((c, partitions) =>
                 {
                     string partitionsStr = string.Join(", ", partitions);
                     Console.WriteLine($"  - Allocated Kafka partition: {PartitionsStr}");
                 })
                 .SetPartitionsRevokedHandler((c, partitions) =>
                 {
                     string partitionsStr = string.Join(", ", partitions);
                     Console.WriteLine($"  - Recycling Kafka partition: {partitionsstr}");
                 })
                 .Build();
                consumer.Subscribe(topics);
                try
                {
                    while (true)
                    {
                        try
                        {
                            var consumeResult = consumer.Consume(cancellationToken);
                            Console.WriteLine($"Consumed message '{consumeResult.Message?.Value}' at: '{consumeResult?.TopicPartitionOffset}'.");
                            if (consumeResult.IsPartitionEOF)
                            {
                                Console.WriteLine($"  - {datetime.now:yyyy-mm-dd hh: mm: ss} has been in the end: {consumeResult.topic}, partition {consumeResult.partition}, offset {consumeresult.offset}.");
                                continue;
                            }
                            TMessage messageResult = null;
                            try
                            {
                                messageResult = JsonConvert.DeserializeObject<TMessage>(consumeResult.Message.Value);
                            }
                            catch (Exception ex)
                            {
                                var errorMessage = $"  - {datetime.now:Yyyy-mm-dd hh: mm: ss} [Exception message reverse sequence failed, value: {consumeResult.Message.Value}]: {EX.STACKTRACE? .Tostring ()}";
                                Console.WriteLine(errorMessage);
                                messageResult = null;
                            }
                            if (messageResult != null/* && consumeResult.Offset % commitPeriod == 0*/)
                            {
                                messageFunc(messageResult);
                                try
                                {
                                    consumer.Commit(consumeResult);
                                }
                                catch (KafkaException e)
                                {
                                    Console.WriteLine(e.Message);
                                }
                            }
                        }
                        catch (ConsumeException e)
                        {
                            Console.WriteLine($"Consume error: {e.Error.Reason}");
                        }
                    }
                }
                catch (OperationCanceledException)
                {
                    Console.WriteLine("Closing consumer.");
                    consumer.Close();
                }
                await Task.CompletedTask;
            }
        }
    copy code

    // producers

    copy code
    string[] configList = { "xxx.xx.xx.xx:9092", "sun" };
    
    //Call the interface definition method
    KafkaService kafkaService = new KafkaService();
    while (true)
    {
        var data = Console.ReadLine();
        await kafkaService.PublishAsync<string>(configList.First(), configList.Last(), data);
    }
    copy code

    //consumer

    copy code
    KafkaService kafkaService = new KafkaService();
    await kafkaService.SubscribeAsync<string>(new string[] { "sun" }, like, new CancellationToken());
    
    static void like(string like)
    {
        Console.WriteLine($"This is acceptable: {like}");
    }
    copy code

    Code instance (Publish / subscription mode)

  • 相关阅读:
    JS获取当前网页大小以及屏幕分辨率等
    JS获取浏览器信息及屏幕分辨率
    vue中获取客户端IP地址(不需要额外引入三方文件)
    vue事件修饰器
    export,import ,export default的区别
    Vue中动态添加多个class
    Vue中通过鼠标移入移出来添加或取消class样式(active)
    restapi(5)- rest-mongo 应用实例:分布式图片管理系统之一,rest 服务
    restapi(4)- rest-mongo : MongoDB数据库前端的httpserver
    restapi(3)- MongoDBEngine : MongoDB Scala编程工具库
  • 原文地址:https://www.cnblogs.com/DomoYao/p/15851984.html
Copyright © 2020-2023  润新知