silky微服務定義了三種類型的代理主機,開發者能夠根據須要選擇合適的silky代理主機託管微服務應用。代理主機定義了一個Startup
模塊,該模塊給出了使用該種類型主機所必須依賴的模塊。html
該類型的主機通常用於託管業務應用,服務內部之間經過rpc進行通訊,不支持與微服務集羣與外部進行通訊,web代理主機能夠經過引用該類型的微服務的應用接口,經過應用接口生成的代理與該微服務進行通訊。該類型的微服務使用.net的通用主機進行託管引用。定義的Startup
模塊以下所示:git
[DependsOn(typeof(ZookeeperModule), typeof(DotNettyTcpModule), typeof(RpcProxyModule), typeof(TransactionTccModule), typeof(ValidationModule), typeof(FluentValidationModule), typeof(RedisCachingModule), typeof(TransactionRepositoryRedisModule) )] public abstract class GeneralHostModule : StartUpModule { }
開發者若是須要建立一個微服務應用,只須要在建立一個控制檯應用,經過nuget包管理工具安裝Silky.Agent.GeneralHost
包,在主函數中註冊SilkyServices
,並指定啓動模塊便可。github
public static async Task Main(string[] args) { await CreateHostBuilder(args).Build().RunAsync(); } private static IHostBuilder CreateHostBuilder(string[] args) { return Host.CreateDefaultBuilder(args) .RegisterSilkyServices<AccountHostModule>() ; }
開發者經過繼承GeneralHostModule
模塊定義啓動模塊。能夠經過DependsOn
依賴自定義的模塊或是Silky提供的模塊。web
啓動模塊以下所示:redis
// // [DependsOn(typeof(SilkySkyApmAgentModule), // typeof(JwtModule), // typeof(MessagePackModule))] public class AccountHostModule : GeneralHostModule { }
該類型的主機能夠經過http端口與外部經過http協議進行通訊,經過引用其餘業務微服務應用的應用接口,根據路由模版生成restful風格的webapi,開發者能夠經過配置生成在線的swagger
文檔。直觀的看到在線api文檔和進行調試。生成的swagger文檔能夠根據引用的應用接口進行分組。算法
web代理主機預約義的Startup
模塊指定了web代理主機必須依賴的silky模塊,以下所示:docker
[DependsOn(typeof(RpcProxyModule), typeof(ZookeeperModule), typeof(SilkyHttpCoreModule), typeof(DotNettyModule), typeof(ValidationModule), typeof(FluentValidationModule), typeof(RedisCachingModule) )] public abstract class WebHostModule : StartUpModule { }
該類型的主機通常用於網關,提供了外部與微服務集羣進行通訊的橋樑,該類型的主機使用.net的web主機進行託管應用。開發者能夠建立一個aspnetcore項目,經過安裝Silky.Agent.WebHost
包便可建立web代理主機,須要同時指定啓動模塊和Startup
類。shell
public async static Task Main(string[] args) { await CreateHostBuilder(args).Build().RunAsync(); } public static IHostBuilder CreateHostBuilder(string[] args) { var hostBuilder = Host.CreateDefaultBuilder(args) .RegisterSilkyServices<GatewayHostModule>() .ConfigureWebHostDefaults(webBuilder => { webBuilder.UseStartup<Startup>(); }); return hostBuilder; }
web代理主機的啓動模塊須要繼承WebHostModule
,啓動模塊GatewayHostModule
以下所示:數據庫
public class GatewayHostModule : WebHostModule { }
須要在Startup
類註冊Silky
請求管道,Startup
類以下所示:json
public class Startup { public Startup(IConfiguration configuration) { Configuration = configuration; } public IConfiguration Configuration { get; } // This method gets called by the runtime. Use this method to add services to the container. public void ConfigureServices(IServiceCollection services) { } // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. public void Configure(IApplicationBuilder app, IWebHostEnvironment env) { if (env.IsDevelopment() || env.EnvironmentName == "ContainerDev") { app.UseDeveloperExceptionPage(); } app.ConfigureSilkyRequestPipeline(); } }
websocket代理主機與通用代理主機基本一致,websocket代理主機具體提供ws服務的能力,web主機能夠經過ws代理與websocket代理主機的ws服務進行通訊。
websocket代理主機的啓動模塊以下所示:
[DependsOn(typeof(ZookeeperModule), typeof(DotNettyTcpModule), typeof(RpcProxyModule), typeof(TransactionTccModule), typeof(WebSocketModule), typeof(ValidationModule), typeof(FluentValidationModule), typeof(RedisCachingModule), typeof(TransactionRepositoryRedisModule) )] public abstract class WebSocketHostModule : StartUpModule { }
開發者能夠經過WebSocket
配置節點對ws服務進行配置,ws服務的默認端口爲3000
,可是通常地,與ws服務創建握手時,不該該與ws服務直接進行握手,而是應該經過web代理主機的代理中間件進行握手,因此若是開發者使用ws服務,必需要在web代理主機安裝Silky.WebSocket.Middleware
。
ws服務的建立與通用代理主機的建立一致,只須要將啓動模塊繼承的基類修改成WebSocketHostModule
便可。
ws服務的定義以下:
public class WsTestAppService : WsAppServiceBase, IWsTestAppService { public async Task Echo(string businessId, string msg) { if (BusinessSessionIds.TryGetValue(businessId, out var sessionIds)) { foreach (var sessionId in sessionIds) { SessionManager.SendTo($"message:{msg},sessionId:{sessionId}", sessionId); } } else { throw new BusinessException($"不存在businessId爲{businessId}的會話"); } } }
須要注意的時,在創建握手過程當中,必需要指定hashkey
從而保證每次回話的微服務實例都是同一個,更多關於ws服務請查看。
silky微服務使用攔截器和filter實現了TCC分佈式事務,在tcc分佈式事務過程當中,將事務參與者的調用參數做爲undolog日誌保存到數據倉庫中(當前實現了redis做爲undo日誌的數據存儲器),並在後臺執行做業檢查分佈式事務的執行狀況,從而保證數據的最終一致性。
[Transaction]
特性進行標識該接口是一個分佈式應用方法。[Transaction] Task<GetOrderOutput> Create(CreateOrderInput input);
[TccTransaction]
特性標識,並指定ConfirmMethod
方法和CancelMethod
,指定實現的ConfirmMethod
方法和CancelMethod
必須爲public
,方法參數與應用實現方法的保持一致。try方法若是須要向ConfirmMethod
方法和CancelMethod
傳遞參數經過RpcContext.Context
進行。[TccTransaction(ConfirmMethod = "OrderCreateConfirm", CancelMethod = "OrderCreateCancel")] [UnitOfWork] public async Task<GetOrderOutput> Create(CreateOrderInput input) { var orderOutput = await _orderDomainService.Create(input); return orderOutput; } [UnitOfWork] public async Task<GetOrderOutput> OrderCreateConfirm(CreateOrderInput input) { var orderId = RpcContext.Context.GetAttachment("orderId"); var order = await _orderDomainService.GetById(orderId.To<long>()); order.Status = OrderStatus.Payed; order.UpdateTime = DateTime.Now; order = await _orderDomainService.Update(order); return order.Adapt<GetOrderOutput>(); } [UnitOfWork] public async Task OrderCreateCancel(CreateOrderInput input) { var orderId = RpcContext.Context.GetAttachment("orderId"); if (orderId != null) { // await _orderDomainService.Delete(orderId.To<long>()); var order = await _orderDomainService.GetById(orderId.To<long>()); order.Status = OrderStatus.UnPay; await _orderDomainService.Update(order); } }
silky的服務定義很是簡單,在這裏的服務指的是應用服務,與傳統MVC的Controller
的概念一致。
您只須要在一個業務微服務應用中,新增應用接口層,通常地,咱們能夠命名爲Project.IApplication
或是Project.Application.Contracts
,並新增應用接口,在應用接口中經過[ServiceRoute]
特性進行標識,並在Project.Application
項目中實現該接口。
您能夠經過[ServiceRoute]
指定該應用服務的路由模板, 以及是否容許多個實現。
例如:
namespace Silky.Account.Application.Contracts.Accounts { /// <summary> /// 帳號服務 /// </summary> [ServiceRoute] public interface IAccountAppService { /// <summary> /// 新增帳號 /// </summary> /// <param name="input">帳號信息</param> /// <returns></returns> Task<GetAccountOutput> Create(CreateAccountInput input); } }
在應用層中實現該接口:
namespace Silky.Account.Application.Accounts { public class AccountAppService : IAccountAppService { private readonly IAccountDomainService _accountDomainService; public AccountAppService(IAccountDomainService accountDomainService) { _accountDomainService = accountDomainService; } public async Task<GetAccountOutput> Create(CreateAccountInput input) { var account = await _accountDomainService.Create(input); return account.Adapt<GetAccountOutput>(); } } }
應用接口能夠被其餘微服務應用或是被網關應用引用。其餘微服務能夠經過應用接口生成代理,並經過內部實現的rpc框架與該微服務進行通訊。silky的rpc通訊支持tcc方式的分佈式事務,詳情見上節。
應用接口被網關引用,web host主機能夠經過該應用服務接口生成相應的webapi,並能夠生成swagger在線文檔。經過http請求,從而實現服務與集羣外部進行通訊,當http請求到達webhost主機後,silky中間件經過webapi和請求方法路由到服務條目,而後經過內部實現的rpc通訊與微服務應用進行通訊。
RPC的過濾器: rpc通訊支持兩種類型的過濾器,在客戶端發起請求過程當中,會依次調用開發者定義的IClientFilter
過濾器,服務端收到請求後,會依次調用IServerFilter
而後再執行應用方法自己。
RpcContext: 能夠經過RpcContext.Context
添加或是獲取本次rpc調用的Attachments
參數。固然,開發者也能夠經過注入IRpcContextAccessor
獲取本次通訊的上線文參數RpcContext
。
獲取當前登陸用戶: 開發者能夠經過NullSession.Instance
獲取當前登陸用戶,若是您已經登陸系統,那麼經過該接口能夠獲取到當前登陸用戶的userId
、userName
等信息。
針對每一個服務條目(應用服務接口方法),都實現了服務治理,開發者能夠經過governance
或是[Governance()]
特性對服務的最大併發量、負載均衡算法、執行超時時間、是否使用緩存攔截、失敗回調接口、接口是否對外網屏蔽等等屬性進行配置。
如下描述了以服務條目爲治理單位的屬性表單:
屬性 | 說明 | 缺省值 | 備註 |
---|---|---|---|
AddressSelectorMode | 負載均衡策略 | Polling(輪詢) | 負載均衡算法支持:Polling(輪詢)、Random(隨機)、HashAlgorithm(哈希一致性,根據rpc參數的第一個參數值) |
ExecutionTimeout | 執行超時時間 | 3000(ms) | 單位爲(ms),超時時發生熔斷,-1表示在rpc通訊過程當中不會超時 |
CacheEnabled | 是否啓用緩存攔截 | true | rpc通訊中是否啓用緩存攔截 |
MaxConcurrent | 容許的最大併發量 | 100 | |
FuseProtection | 是否開啓熔斷保護 | true | |
FuseSleepDuration | 熔斷休眠時長 | 60(s) | 發生熔斷後,多少時長後再次重試該服務實例 |
FuseTimes | 服務提供者容許的熔斷次數 | 3 | 服務實例連續n次發生熔斷端,服務實例將被標識爲不健康 |
FailoverCount | 故障轉移次數 | 0 | rpc通訊異常狀況下,容許的從新路由服務實例的次數,0表示有幾個服務實例就轉移幾回 |
ProhibitExtranet | 是否禁止外網訪問 | false | 該屬性只容許經過GovernanceAttribute 特性進行設置 |
FallBackType | 失敗回調指定的類型 | null | 類型爲Type ,若是指定了失敗回調類型,那麼在服務執行失敗,則會執行該類型的Invoke 方法,該類型,必需要繼承IFallbackInvoker 該接口 |
開發者還能夠經過[Governance()]
特性對某個服務方法進行標識,被該特性標識的治理屬性將覆蓋微服務的配置/缺省值。
爲提升應用的響應,silky支持緩存攔截。緩存攔截在應用服務接口方法上經過緩存攔截特性進行設置,在silky框架中,存在以下三中類型的緩存特性,分別對數據緩存進行新增、更新、刪除。
設置緩存特性--GetCachingInterceptAttribute
更新緩存特性--UpdateCachingInterceptAttribute
刪除緩存特性--RemoveCachingInterceptAttribute
使用緩存攔截,必需要保證緩存一致性。在rpc通訊過程當中,使用緩存攔截,同一數據的緩存依據可能會不一樣(設置的KeyTemplate
,例如:緩存依據可能會根據Id
、Name
、Code
分別進行緩存),從而產生不一樣的緩存數據,可是在對數據進行更新、刪除操做時,因爲沒法經過RemoveCachingInterceptAttribute
特性一次性刪除該類型數據的全部緩存數據,這個時候,在實現業務代碼過程當中,就須要經過分佈式緩存接口IDistributedCache<T>
實現緩存數據的更新、刪除操做。
silky使用zookeeper做爲默認服務的註冊中心。當前還未擴展支持其餘的服務註冊中心。
silky支持爲微服務集羣配置多個服務註冊中心,您只須要在配置服務註冊中心的連接字符串registrycenter:connectionStrings
中,使用分號;
就能夠指定微服務框架的多個服務註冊中心。
爲微服務配置服務註冊中心以下所示:
registrycenter: // 服務註冊中心配置節點 connectionStrings: 127.0.0.1:2181,127.0.0.1:2182,127.0.0.1:2183;127.0.0.1:2184,127.0.0.1:2185,127.0.0.1:2186 // 服務配置中心連接 registryCenterType: Zookeeper // 註冊中心類型 connectionTimeout: 1000 // 連接超時時間(單位:ms) sessionTimeout: 2000 // 會話超時時間(單位:ms) operatingTimeout: 4000 // 操做超時時間(單位:ms) routePath: /services/serviceroutes
silky框架存在兩種類型的模塊:
SilkyModule
就能夠定義一個普通模塊類;StartUpModule
定義一個服務註冊啓動模塊類;開發者也能夠經過繼承StartUpModule
,選擇合適的依賴包,實現本身的代理主機。模塊的依賴關係: silky框架的模塊經過DependsOn
特性指定模塊的依賴關係,silky框架支持經過直接或是間接的依賴模塊。
經過繼承依賴注入標識接口實現服務的註冊(推薦)
silky框架提供了三個依賴註冊的相關標識接口:ISingletonDependency
(單例模式)、IScopedDependency
(區域模式)、ITransientDependency
(瞬態模式)。在微服務應用啓動時,會掃描繼承了這些標識接口的類(服務),並將其自身和繼承的接口註冊到Ioc容器中。
定義模塊,並在模塊中經過RegisterServices()
方法的ContainerBuilder
註冊服務(autofac),或是經過ConfigureServices()
方法的IServiceCollection
註冊服務(微軟官方自帶的ioc容器)
經過繼承IConfigureService
或是ISilkyStartup
,經過Configure()
方法的IServiceCollection
註冊服務
Silky由於支持經過IServiceCollection
進行服務註冊,因此能夠很方便的與第三方服務(組件)進行整合,例如:CAP
或是MassTransit
等分佈式事件框架。
silky框架提供了serilog
做爲日誌記錄器。只須要在構建主機時,增長UseSerilogDefault()
,並添加Serilog
相關配置便可。
代碼:
public static async Task Main(string[] args) { await CreateHostBuilder(args).Build().RunAsync(); } private static IHostBuilder CreateHostBuilder(string[] args) { var hostBuilder = Host.CreateDefaultBuilder(args) .RegisterSilkyServices<OrderHostModule>() .UseSerilogDefault(); return hostBuilder; }
配置:
serilog: minimumLevel: default: Information override: Microsoft: Warning Microsoft.Hosting.Lifetime: Information Silky: Debug writeTo: - name: File args: path: "./logs/log-.log" rollingInterval: Day - name: Console args: outputTemplate: "[{Timestamp:yyyy/MM/dd HH:mm:ss} {Level:u11}] {Message:lj} {NewLine}{Exception}{NewLine}" theme: "Serilog.Sinks.SystemConsole.Themes.SystemConsoleTheme::Literate, Serilog.Sinks.Console"
要求必須在web主機項目(通常爲網關項目)安裝Silky.Http.MiniProfiler
包,並將swaggerDocument:injectMiniProfiler
配置項的屬性設置爲true
。
swaggerDocument: injectMiniProfiler: true
要求微服務在啓動模塊依賴SilkySkyApmAgentModule
模塊,並配置skyWalking
相關屬性。
[DependsOn(typeof(SilkySkyApmAgentModule))] public class AccountHostModule : GeneralHostModule { }
skyWalking: serviceName: AccountHost headerVersions: - sw8 sampling: samplePer3Secs: -1 percentage: -1.0 logging: level: Debug filePath: "logs/skyapm-{Date}.log" transport: interval: 3000 protocolVersion: v8 queueSize: 30000 batchSize: 3000 gRPC: servers: "127.0.0.1:11800" timeout: 10000 connectTimeout: 10000 reportTimeout: 600000
在silky的實例項目中,提供了skyWalking
經過docker-compose
快速啓動的服務編排文件samples\docker-compose\infrastr\docker-compose.skywalking.yml
,開發者只須要進入到samples\docker-compose\infrastr
目錄中,經過以下命令便可開始的啓動一個skyWalking服務。
cd samples\docker-compose\infrastr docker-compose -f docker-compose.skywalking.yml
打開http://127.0.0.1:8180
便可看到微服務集羣的運行狀況:
網絡拓撲圖:
鏈路跟蹤:
儀表盤:
必要前提是開發者已經部署了一套Apollo服務。開發者能夠參考Apollo部署節點,部署一套Apollo服務。
在開發過程當中,更簡單的作法是使用silky實例項目中使用docker-compose已經編排好的文件 docker-compose.apollo.yml
。
進入到samples\docker-compose\infrastr
目錄,將.env
設置的環境變量EUREKA_INSTANCE_IP_ADDRESS
修改成您當前本機的IP地址,不容許爲127.0.0.1
。
運行以下命令,等待1~2分鐘便可啓動apollo配置服務。
docker-compose -f docker-compose.apollo.yml up -d
在主機項目經過nuget安裝Silky.Apollo
包。(這是一個空包,您也能夠直接安裝Com.Ctrip.Framework.Apollo.AspNetCoreHosting
和Com.Ctrip.Framework.Apollo.Configuration
包)
在服務註冊時,添加對Appo服務配置中心的支持
private static IHostBuilder CreateHostBuilder(string[] args) { return Host.CreateDefaultBuilder(args) .RegisterSilkyServices<AccountHostModule>() .AddApollo(); }
若是您您想在指定的運行環境中使用Apollo做爲微服務的配置中心,而在另外其餘運行環境中使用本地配置,那麼您也能夠經過以下當時處理:
private static IHostBuilder CreateHostBuilder(string[] args) { var hostBuilder = Host.CreateDefaultBuilder(args) .RegisterSilkyServices<AccountHostModule>() .UseSerilogDefault(); if (EngineContext.Current.IsEnvironment("Apollo")) { hostBuilder.AddApollo(); } return hostBuilder; }
備註
運行環境您能夠經過修改Properties\launchSettings.json
的DOTNET_ENVIRONMENT
變量(本地開發模式)
或是經過.env
環境變量文件指定DOTNET_ENVIRONMENT
變量(docker-compose開發模式)
打開地址:http://127.0.0.1:8070 (Applo服務的web管理工具:portal),新建相關的應用。以下圖:
爲應用添加相應的配置:
普通業務微服務的配置以下:
# Application rpc:port = 2201 connectionStrings:default = server=127.0.0.1;port=3306;database=order;uid=root;pwd=qwe!P4ss; jwtSettings:secret = jv1PZkwjLVCEygM7faLLvEhDGWmFqRUW # TEST1.silky.sample registrycenter:registryCenterType = Zookeeper registrycenter:connectionStrings = 127.0.0.1:2181,127.0.0.1:2182,127.0.0.1:2183;127.0.0.1:2184,127.0.0.1:2185,127.0.0.1:2186 distributedCache:redis:isEnabled = true distributedCache:redis:configuration = 127.0.0.1:6379,defaultDatabase=0 rpc:token = ypjdYOzNd4FwENJiEARMLWwK0v7QUHPW governance:executionTimeout = -1 cap:rabbitmq:hostName = 127.0.0.1 cap:rabbitmq:userName = rabbitmq cap:rabbitmq:password = rabbitmq
web網關的配置以下:
# TEST1.silky.sample.gateway gateway:injectMiniProfiler = true gateway:enableSwaggerDoc = true gateway:wrapResult = true gateway:jwtSecret = jaoaNPA1fo1rcPfK23iNufsQKkhTy8eh swaggerDocument:organizationMode = Group swaggerDocument:injectMiniProfiler = true swaggerDocument:termsOfService = https://www.github.com/liuhll/silky # TEST1.silky.sample registrycenter:registryCenterType = Zookeeper registrycenter:connectionStrings = 127.0.0.1:2181,127.0.0.1:2182,127.0.0.1:2183;127.0.0.1:2184,127.0.0.1:2185,127.0.0.1:2186 distributedCache:redis:isEnabled = true distributedCache:redis:configuration = 127.0.0.1:6379,defaultDatabase=0 rpc:token = ypjdYOzNd4FwENJiEARMLWwK0v7QUHPW governance:executionTimeout = -1
appsettings.yml
),若是指定運行環境變量則讀取appsettings.{Environment}.yml
中的配置例如:
apollo: appId: "silky-stock-host" cluster: default metaServer: "http://127.0.0.1:8080/" # secret: "ffd9d01130ee4329875ac3441c0bedda" namespaces: - application - TEST1.silky.sample env: DEV meta: DEV: "http://127.0.0.1:8080/" PRO: "http://127.0.0.1:8080/"
silky使用DistributedLock做爲分佈式鎖,在服務路由註冊和分佈式事務做業中均使用了分佈式鎖.
silky身份認證與受權經過包Silky.Http.Identity
,經過webhost在網關實現統一的身份認證和受權。
silky經過Silky.Jwt
包提供的IJwtTokenGenerator
實現jwt格式的token。簽發token的微服務應用須要經過nuget安裝Silky.Jwt
包,並在啓動模塊中依賴JwtModule
模塊。開發者能夠對簽發的token的密鑰、token有效期、Jwt簽名算法、簽發者、受衆等屬性經過配置節點jwtSettings
進行配置。開發者至少須要對jwtSettings:secret
進行配置。
配置以下:
jwtSettings: secret: jv1PZkwjLVCEygM7faLLvEhDGWmFqRUW
用戶登錄接口以下:
public async Task<string> Login(LoginInput input) { var userInfo = await _accountRepository.FirstOrDefaultAsync(p => p.UserName == input.Account || p.Email == input.Account); if (userInfo == null) { throw new AuthenticationException($"不存在帳號爲{input.Account}的用戶"); } if (!userInfo.Password.Equals(_passwordHelper.EncryptPassword(userInfo.UserName, input.Password))) { throw new AuthenticationException("密碼不正確"); } var payload = new Dictionary<string, object>() { { ClaimTypes.UserId, userInfo.Id }, { ClaimTypes.UserName, userInfo.UserName }, { ClaimTypes.Email, userInfo.Email }, }; return _jwtTokenGenerator.Generate(payload); }
IdentityModule
模塊[DependsOn(typeof(IdentityModule))] public class GatewayHostModule : WebHostModule { }
gateway:jwtSecret
配置的屬性必須與簽發token的微服務應用配置的屬性jwtSettings:secret
的值保持一致。gateway: jwtSecret: jv1PZkwjLVCEygM7faLLvEhDGWmFqRUW
開發者只須要在應用接口或是應用接口方法中標註[AllowAnonymous]
特性便可,這樣無需用戶登錄,也能夠訪問該接口。
[AllowAnonymous] Task<string> Login(LoginInput input);
開發者能夠在網關應用經過繼承SilkyAuthorizationHandler
基類,並重寫PipelineAsync
方法便可實現對自定義受權。
public class TestAuthorizationHandler : SilkyAuthorizationHandler { private readonly ILogger<TestAuthorizationHandler> _logger; private readonly IAuthorizationAppService _authorizationAppService; public TestAuthorizationHandler(ILogger<TestAuthorizationHandler> logger, IAuthorizationAppService authorizationAppService) { _logger = logger; _authorizationAppService = authorizationAppService; } public async override Task<bool> PipelineAsync(AuthorizationHandlerContext context, DefaultHttpContext httpContext) { // 獲取訪問的服務條目 var serviceEntry = httpContext.GetServiceEntry(); // 能夠經過rpc調用IdentifyApp,實現自定義的受權 return _authorizationAppService.Authorization(sserviceEntry.ServiceDescriptor.Id); } }
silky實現了基於AutoMapper和Mapster的對象屬性映射的包。實現的代理主機默認依賴MapsterModule
包,使用Mapster做爲對象映射的組件。
只須要經過Adapt
方法便可實現對象屬性映射。
efcore數據訪問組件主要參考了furion的實現。提供了數據倉庫、數據庫定位器、多租戶等實現方式。使用方式與其基本保持一致。
github: https://github.com/liuhll/silky
gitee: https://gitee.com/liuhll2/silky
開發者文檔: http://docs.silky-fk.com/