Anno微服务引擎与传统应用相融合

1、Anno是什么?

  Anno是一个微服务引擎。在此之前我们通过 Viper项目对Anno有一个基本的认识,并且Viper也受到的很多朋友的喜欢,截止发稿前Viper在GitHub收获了300多个星。并且Anno也在昨天(2020年11月24日)开源。今天我们就聊一聊Anno如何与传统的项目相结合。

github   ://github.com/duyanming/Anno.Core  

gitee      ://gitee.com/duyanming/anno.core

体验地址://140.143.207.244/Home/Login

2、Anno和传统项目相结合

  我们新建一个asp.net framework WebApi 项目。然后我们通过客户端代理(Install-Package Anno.Rpc.Client.DynamicProxy)生成服务接口代理类,并注入到Autofac容器中去。服务提供方可以是.netcore服务、.netframework服务、java服务以及其他语言提供的服务(期待大佬的加入扩展出更多)。

  Demo地址://github.com/duyanming/Viper/tree/master/Samples

  以下Demo我们用.netcore提供服务。

 创建一个传统的ASP.NET WEB API项目,结构如下:

第一步 引入Nuget包 :

Install-Package Anno.Rpc.Client.DynamicProxy -Version 1.0.2.8
Install-Package Autofac.WebApi2 -Version 4.3.1

第二步:

  新增文件:IocManager.cs  

 1  public static class IocManager
 2     {
 3         public static IContainer IoContainer;
 4         private static readonly ContainerBuilder Builder = new ContainerBuilder();
 5 
 6         public static ContainerBuilder GetContainerBuilder()
 7         {
 8             return Builder;
 9         }
10 
11         public static void Build(params Assembly[] assemblies)
12         {
13             if (assemblies != null)
14             {
15                 assemblies.ToList().ForEach(assembly =>
16                 {
17                     assembly.GetTypes().Where(x => x.GetTypeInfo().IsClass && !x.GetTypeInfo().IsAbstract && !x.GetTypeInfo().IsInterface).ToList().ForEach(
18                         t =>
19                         {
20                             var interfaces = t.GetInterfaces();
21                             if (interfaces.Length <= 0)
22                             {
23                                 Builder.RegisterType(t);
24                             }
25                             else
26                             {
27                                 Builder.RegisterType(t).As(t.GetInterfaces());
28                             }
29                         });
30                 });
31 
32             }
33             IoContainer = Builder.Build();
34         }
35     }

  新增文件:AutoFacConfig.cs  

 1 public class AutoFacConfig
 2     {
 3         public static void Register()
 4         {
 5             var builder = IocManager.GetContainerBuilder();
 6             var config = GlobalConfiguration.Configuration;
 7 
 8             builder.RegisterApiControllers(Assembly.GetCallingAssembly())
 9                .PropertiesAutowired();
10             builder.RegisterWebApiFilterProvider(config);
11             builder.RegisterWebApiModelBinderProvider();
12             /*
13              * Anno服务接口通过代理注册到IOC容器中去
14              */
15             builder.RegisterInstance<IHelloWorldViperService>(AnnoProxyBuilder.GetService<IHelloWorldViperService>());
16 
17             IocManager.Build(typeof(IocManager).Assembly);
18             config.DependencyResolver = new AutofacWebApiDependencyResolver(IocManager.IoContainer);
19 
20 
21         }
22     }

  修改文件:WebApiConfig.cs  

 1 public static class WebApiConfig
 2     {
 3         public static void Register(HttpConfiguration config)
 4         { 
 5             //1、将默认的xml格式化程序清除
 6             GlobalConfiguration.Configuration.Formatters.XmlFormatter.SupportedMediaTypes.Clear();
 7 
 8             // Web API 配置和服务
 9 
10             // Web API 路由
11             config.MapHttpAttributeRoutes();
12 
13             config.Routes.MapHttpRoute(
14                 name: "DefaultApi",
15                 routeTemplate: "api/{controller}/{id}",
16                 defaults: new { id = RouteParameter.Optional }
17             );
18             config.Formatters.JsonFormatter.SerializerSettings.DateFormatString = "MM/dd/yyy HH:mm:ss";
19         }
20     }

  修改文件:Global.asax  

 1  using Anno.Rpc.Client;
 2     public class WebApiApplication : System.Web.HttpApplication
 3     {
 4         protected void Application_Start()
 5         {
 6             /*
 7              * 配置注册中心地址
 8              * 客户端名称:MvcCallAnno
 9              * 注册中心IP:127.0.0.1
10              * 注册中心端口:7010
11              * 调用链追踪:false(true开启,false关闭)
12              */
13             DefaultConfigManager.SetDefaultConfiguration("MvcCallAnno", "127.0.0.1", 7010, true);
14             /*
15              * Autofac Ioc 初始化
16              */
17             AutoFacConfig.Register();
18             GlobalConfiguration.Configure(WebApiConfig.Register);
19         }
20     }

  增加服务接口:IHelloWorldViperService.cs  

 1 namespace MvcCallAnno.Service
 2 {
 3     using Anno.Rpc.Client.DynamicProxy;
 4 
 5     /// <summary>
 6     /// 对应Anno.Plugs.HelloWorldService 插件的 HelloWorldViperModule 模块
 7     /// 接口名称和接口方法和 AnnoService端的 名称不一样的时候使用AnnoProxy 指定别名
 8     /// </summary>
 9     [AnnoProxy(Channel = "Anno.Plugs.HelloWorld", Router = "HelloWorldViper")]
10     public interface IHelloWorldViperService
11     {
12         /// <summary>
13         /// 名称不一致
14         /// </summary>
15         /// <param name="name"></param>
16         /// <param name="age"></param>
17         /// <returns></returns>
18         [AnnoProxy(Method = "SayHello")]
19         dynamic SayHello(string name, int age);
20         /// <summary>
21         /// 名称一致
22         /// </summary>
23         /// <param name="x"></param>
24         /// <param name="y"></param>
25         /// <returns></returns>
26         int Subtraction(int x, int y);
27 
28         ProductDto BuyProduct(string productName, int number);
29     }
30 
31 
32     public class ProductDto
33     {
34         public string Name { get; set; }
35         public int Number { get; set; }
36         public double Price { get; set; }
37         public double Amount { get { return Price * Number; } }
38         public string CountryOfOrigin { get; set; }
39     }
40 }

  增加控制器:ValuesController.cs   

 1   public class ValuesController : ApiController
 2     {
 3         private readonly IHelloWorldViperService helloWorldViperService;
 4         public ValuesController(IHelloWorldViperService helloWorldViperService) {
 5             this.helloWorldViperService = helloWorldViperService;
 6         }
 7         [HttpGet]
 8         public dynamic SayHello(string name, int age) {
 9             var rlt= helloWorldViperService.SayHello(name,age);
10             return Json(rlt);
11         }
12         [HttpGet]
13         public int Subtraction(int x, int y) {
14             return helloWorldViperService.Subtraction(x,y);
15         }
16         [HttpGet]
17         public dynamic BuyProduct(string productName, int number) {
18             return helloWorldViperService.BuyProduct(productName, number);
19         }

 主要步骤:

安装Nuget包—》初始化Anno注册中心配置—-》代理注入AutoFac容器—》控制器通过构造函数注入服务接口

2.1、开始演示

1、启动注册中心

 2、启动HelloWorldService服务

  再来看下注册中心输出的信息

 注册中心已经收到HelloWorldService服务的注册

3、启动我们的Asp.net Web API

  调用控制器接口:SayHello  

[HttpGet]
        public dynamic SayHello(string name, int age) {
            var rlt= helloWorldViperService.SayHello(name,age);
            return Json(rlt);
        }

 

 看到了输出结果,第一个接口调用成功。

  第二个接口:Subtraction  

1  [HttpGet]
2         public int Subtraction(int x, int y) {
3             return helloWorldViperService.Subtraction(x,y);
4         }

 

  看到了输出结果75,也是我们预期的结果。调用成功。

  第三个接口:BuyProduct

  

1 [HttpGet]
2         public dynamic BuyProduct(string productName, int number) {
3             return helloWorldViperService.BuyProduct(productName, number);
4         }

  也是我们预期的结果。调用成功。

 

学习交流 QQ群:478399354 ,到这里我们互为师长项目学习。

Anno核心源码://github.com/duyanming/Anno.Core  

Viper示例项目://github.com/duyanming/Viper  

体验地址://140.143.207.244/Home/Login

文档地址://duyanming.github.io/

关于Anno的更多内容,随后更新。敬请关注。开源不易,感谢Star。