surging Community Edition supports .net core 3.1

Brief introduction

surging after two years of research and development, micro-services engine has slightly prototype, also courtesy of you for your love, on GitHub harvest nearly 2800 stars, fork 811, subscribers have more than a dozen companies, as well as consulting and training,

In 2020, we will rely on the power of the community, to improve community version, but will spend more energy to maintain good paying customers we can work together to build a community surging, there are ten days will the New Year, everyone can join the only official surging population: 615 562 965, when the New Year red envelopes will be issued as usual, but also a lot of oh. Let the New Year carnival together.

 surging will have its own official station, the authors are being developed with VuePress, we will meet you in the near days

New Function Description

1.GRPC protocol support:

Add interfaces, the default value is set ServerCallContext parameter is null. code show as below:

 

using Greet;
using Grpc.Core;
using Surging.Core.CPlatform.Ioc;
using Surging.Core.CPlatform.Runtime.Server.Implementation.ServiceDiscovery.Attributes;
using System.Threading.Tasks;

namespace Surging.IModuleServices.Common
{
    [ServiceBundle("api/{Service}/{Method}")]
    public  interface IGreeterService : IServiceKey
    {
        Task<HelloReply> SayHello(HelloRequest request, ServerCallContext context=null);
    }
}

Add GreeterBehavior, the following code

using Greet;
using Surging.Core.CPlatform.Ioc;

namespace Surging.Modules.Common.GreeterServices
{
    public  partial class GreeterBehavior : Greeter.GreeterBase,IServiceBehavior
    {
        
    }
}

 Add business code, the code is as follows:

using Greet;
using Grpc.Core;
using Surging.IModuleServices.Common;
using Surging.Modules.Common.GreeterServices;

using System.Threading.Tasks;

namespace Surging.Modules.Common.Domain
{
    public class GreeterService: GreeterBehavior, IGreeterService
    {
        public override Task<HelloReply> SayHello(HelloRequest request, ServerCallContext context)
        {
            return Task.FromResult(new HelloReply
            {
                Message = "Hello " + request.Name
            });
        }
    }
}

GRPC client calls, the code is as follows

using Greet;
using Grpc.Core;
using System;

namespace GrpcService1
{
    public class Program
    {
        public static void Main(string[] args)
        {
           var  channel = new Channel("127.0.0.1", 95, ChannelCredentials.Insecure);
           var client = new Greeter.GreeterClient(channel);
            var result = client.SayHello(new HelloRequest
            {
                Name = "fanly"
            });

            Console.WriteLine("grpc Client Call SayHello():" + result); 
            Console.ReadKey();
        } 
    }
}

2. Support WorkService background daemon hosting

WorkService engine supports back-office services, can support remote RPC call to open, close, add-tasking, as follows:

Add interface code as follows:

   [ServiceBundle("Background/{Service}")]
    public interface IWorkService : IServiceKey
    {
        Task<bool> AddWork(Message message);

         Task StartAsync();

        Task StopAsync();
    }

Then you need to inherit BackgroundServiceBehavior , and service life cycle is set to ISingleInstance

 public class WorkService : BackgroundServiceBehavior, IWorkService, ISingleInstance
    {
        private readonly ILogger<WorkService> _logger;
        private   readonly Queue<Message> _queue = new Queue<Message>();
        private readonly IServiceProxyProvider _serviceProxyProvider;
        private CancellationToken _token;

        public WorkService(ILogger<WorkService> logger, IServiceProxyProvider serviceProxyProvider)
        {
            _logger = log;
            _serviceProxyProvider = serviceProxyProvider;
        }

        public  Task<bool> AddWork(Message message)
        {
            _queue.Enqueue(message);
            return Task.FromResult(true);
        }

        protected override async  Task ExecuteAsync(CancellationToken stoppingToken)
        {
            try
            {
                _token = stoppingToken;
                _logger.LogInformation("Worker running at: {time}", DateTimeOffset.Now);
                _queue.TryDequeue(out Message message);
                if (message != null)
                {
                    var result = await _serviceProxyProvider.Invoke<object>(message.Parameters, message.RoutePath, message.ServiceKey);
                    _logger.LogInformation("Invoke Service at: {time},Invoke result:{result}", DateTimeOffset.Now, result);
                }
                if (!_token.IsCancellationRequested)
                    await Task.Delay(1000, stoppingToken);
            }
            catch (Exception ex){
                _logger.LogError("WorkService execute error, message:{message} ,trace info:{trace} ", ex.Message, ex.StackTrace);
            }
        }

        public async Task StartAsync()
        {
            if (_token.IsCancellationRequested)
            { 
                await base.StartAsync(_token);
            }
        }

        public async Task StopAsync()
        {
            if (!_token.IsCancellationRequested)
            {
               await  base.StopAsync(_token);
            }
        }
    }

3. Support characteristic verification

Support validation interface characteristics, as follows

   [ServiceBundle("api/{Service}/{Method}")]
    //[ServiceBundle("api/{Service}")]
    //[ServiceBundle("api/{Service}/{Method}/test")]
    //[ServiceBundle("api/{Service}/{Method}/test",false)]
    public interface IUserService: IServiceKey
    {
        ///  <Summary> 
        /// Get user's name
         ///  </ Summary> 
        ///  <param name = "ID"> User ID </ param> 
        ///  <Returns> </ Returns> 
        [ServiceRoute ( " ID} { " )]
        The Task < String > the GetUserName ([the Validate] [the Range ( . 1 , 10 , the ErrorMessage = " only 1 to 10 " )] int ID);


 ///  <Summary> 
        /// Get user
         ///  </ Summary> 
        ///  <param name = "User"> user model </ param> 
        ///  <Returns> </ Returns> 
        [the Command (= Strategy StrategyType.Injection, Injection = @ " return
new Surging.IModuleServices.Common.Models.UserModel
         {
            Name=""fanly"",
            Age=19
         };", RequestCacheEnabled = true, InjectionNamespaces = new string[] { "Surging.IModuleServices.Common" })]
        [InterceptMethod(CachingMethod.Get, Key = "GetUser_id_{0}", CacheSectionType = SectionType.ddlCache, Mode = CacheTargetType.Redis, Time = 480)]
        [Validate]
        Task<UserModel> GetUser(UserModel user);
          

}

Support characteristics model validation, add interface method must be [the Validate] properties, or else not be verified, as follows

   [ProtoContract]
    public class UserModel
    {

        [ProtoMember ( 1 )]
        [CacheKey(1)]
        public int UserId { get; set; }

        [ProtoMember(2)]
        public string Name { get; set; }

        [ProtoMember ( 3 )]
        [The Range ( 0 , 150 , the ErrorMessage = " Age only between 0 and 150 years " )]
         public  int Age { GET ; SET ;}

        [ProtoMember ( 4 )]
        [The Range ( 0 , . 1 , the ErrorMessage = " Gender male or female can only choose " )]
         public Sex Sex { GET ; SET ;}

    }

to sum up

Open source is not easy, please support

 

Guess you like

Origin www.cnblogs.com/fanliang11/p/12171032.html