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。