Anno微服務引擎與傳統應用相融合

杜燕明發表於2020-11-25

1、Anno是什麼?

  Anno是一個微服務引擎。在此之前我們通過 Viper專案對Anno有一個基本的認識,並且Viper也受到的很多朋友的喜歡,截止發稿前Viper在GitHub收穫了300多個星。並且Anno也在昨天(2020年11月24日)開源。今天我們就聊一聊Anno如何與傳統的專案相結合。

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

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

體驗地址:http://140.143.207.244/Home/Login

2、Anno和傳統專案相結合

  我們新建一個asp.net framework WebApi 專案。然後我們通過客戶端代理(Install-Package Anno.Rpc.Client.DynamicProxy)生成服務介面代理類,並注入到Autofac容器中去。服務提供方可以是.netcore服務、.netframework服務、java服務以及其他語言提供的服務(期待大佬的加入擴充套件出更多)。

  Demo地址:https://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核心原始碼:https://github.com/duyanming/Anno.Core  

Viper示例專案:https://github.com/duyanming/Viper  

體驗地址:http://140.143.207.244/Home/Login

文件地址:https://duyanming.github.io/

關於Anno的更多內容,隨後更新。敬請關注。開源不易,感謝Star。 

相關文章