# LinFx **Repository Path**: NeedLoss/LinFx ## Basic Information - **Project Name**: LinFx - **Description**: https://github.com/linfx/LinFx 同步库 - **Primary Language**: Unknown - **License**: MIT - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2020-02-03 - **Last Updated**: 2020-12-19 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # LinFx [![](https://img.shields.io/badge/.NET%20Core-2.0.0-brightgreen.svg?style=flat-square)](https://www.microsoft.com/net/download/core) [![Build status](https://ci.appveyor.com/api/projects/status/33srpo7owl1h3y4e?svg=true)](https://ci.appveyor.com/project/rabbitmq/rabbitmq-dotnet-client) [![GitHub license](https://img.shields.io/badge/license-MIT-brightgreen.svg?style=flat-square)](https://github.com/linfx/LinFx/blob/master/LICENSE) 一个基于 .NET Core 2.0 开发的简单易用的快速开发框架,遵循领域驱动设计(DDD)规范约束,提供实现事件驱动、事件回溯、响应式等特性的基础设施。让开发者享受到正真意义的面向对象设计模式来带的美感。 官方交流群: 241445317 *** ## LinFx.Extensions Polly、FluentValidation、Metrics - Auditing (审核日志) - Caching (缓存 Memory Distributed) - Dapper - Data (DataFilter) - Elasticsearch - EntityFrameworkCore - EventBus - EventStores (ES) - Hangfire - Mediator - MongoDB - MultiTenancy (多租用户) - RabbitMQ *** ## LinFx.Utils 各日常工具类集合 - EncryptUtils - JsonUtils *** ### 特性 1. 领域驱动设计 (DDD) 2. 事件驱动架构 (EDA) 3. 事件回溯 (ES) 4. 最终一致性 (Eventually Consistent) 6. 框架中每个组件都有基础实现,最简单时只需一个核心类库就能跑起来 7. 遵循端口与适配器模式,框架组件适配多种第三方组件实现,可从单体架构到面向服务架构按需扩展 ### 知识点 1. 领域驱动设计(Domain Driven Design (Layers and Domain Model Pattern) 2. 命令查询职责分离(CQRS:Command Query Responsibility Segregation) 3. 领域通知 (Domain Notification) 5. 领域驱动 (Domain Events) 6. 事件驱动架构 (EDA) 7. 事件回溯 (Event Sourcing) 8. 最终一致性 (Eventually Consistent) 9. 工作单元模式 (Unit of Work ) 10. 泛型仓储 (Repository and Generic Repository) ### 设计规范 1. 尽量使用.NET Standard和官方提供的类库,第三方类库设计成组件利用DI来按需组合。 ### 安装Nuget包 ``` doc PM> Install-Package LinFx ```` ### 开发环境 1. Visual Studio 15.3+ 2. .NET Core SDK 2.2+ *** ### Samples ``` cs public void ConfigureServices(IServiceCollection services) { services.AddLinFx() .AddDistributedRedisCache(options => { options.Configuration = configuration.GetConnectionString("ReidsConnection"); }) .AddMongoDBContext(options => { options.Name = "default"; options.Configuration = configuration.GetConnectionString("MongoConnection"); }) .AddElasticsearch(options => { options.DefaultIndex = "default"; options.Host = "http://10.0.1.112:9200"; }); } `````` ### EventBus ``` cs using LinFx.Extensions.EventBus.Abstractions; using LinFx.Test.Extensions.EventBus.Events; using LinFx.Utils; using LinFx.Extensions.EventBus.RabbitMQ; using Microsoft.Extensions.DependencyInjection; using System.Threading.Tasks; using Xunit; using LinFx.Test.Extensions.EventBus.EventHandling; using System.Collections.Generic; using System; namespace LinFx.Test.Extensions.EventBus { public class EventBusRabbitMQTest { private readonly IEventBus _eventBus; public EventBusRabbitMQTest() { var services = new ServiceCollection(); services.AddLinFx() .AddEventBus(options => { options.Durable = true; options.BrokerName = "tc_cloud_event_bus"; options.QueueName = "tc_cloud_process_queue"; options.ConfigureEventBus = (fx, builder) => builder.UseRabbitMQ(fx, x => { x.Host = "14.21.34.85"; x.UserName = "admin"; x.Password = "admin.123456"; }); }); //services services.AddTransient(); //services.AddTransient(); var applicationServices = services.BuildServiceProvider(); //ConfigureEventBus _eventBus = applicationServices.GetRequiredService(); _eventBus.Subscribe(); //eventBus.Subscribe(); } [Fact] public async Task Should_Call_Handler_On_Event_With_Correct_SourceAsync() { var orderId = Guid.NewGuid().GetHashCode() & ushort.MaxValue; var evt = new OrderStatusChangedToAwaitingValidationIntegrationEvent(orderId, new List { }); await _eventBus.PublishAsync(evt); //for (int i = 0; i < 2; i++) //{ // await _eventBus.PublishAsync(new ClientCreateIntergrationEvent // { // ClientId = IDUtils.CreateNewId().ToString(), // ClientSecrets = new[] { "191d437f0cc3463b85669f2b570cdc21" }, // AllowedGrantTypes = new[] { "client_credentials" }, // AllowedScopes = new[] { "api3.device" } // }); //} } } } ``` ### RedisCache ``` cs using Microsoft.Extensions.Caching.Distributed; using Microsoft.Extensions.DependencyInjection; using Xunit; namespace LinFx.Test.Caching { public class RedisCacheTest { IDistributedCache _cache; public RedisCacheTest() { var services = new ServiceCollection(); services.AddLinFx() .AddDistributedRedisCache(options => { options.Configuration = "10.0.1.112:6379,password=redis"; options.InstanceName = "linfx_test:"; }); var container = services.BuildServiceProvider(); _cache = container.GetService(); } [Fact] public void GetMissingKeyReturnsNull() { string key = "non-existent-key"; var result = _cache.Get(key); Assert.Null(result); } [Fact] public void SetAndGetReturnsObject() { var value = new byte[1]; string key = "myKey"; _cache.Set(key, value); var result = _cache.Get(key); Assert.Equal(value, result); } [Fact] public void SetAndGetWorksWithCaseSensitiveKeys() { var value = new byte[1]; string key1 = "myKey"; string key2 = "Mykey"; _cache.Set(key1, value); var result = _cache.Get(key1); Assert.Equal(value, result); result = _cache.Get(key2); Assert.Null(result); } } } ``` ### MemoryCache ``` cs using Microsoft.Extensions.Caching.Distributed; using Microsoft.Extensions.Caching.Memory; using Microsoft.Extensions.DependencyInjection; using Xunit; namespace LinFx.Test.Caching { public class MemoryCacheTest { [Fact] public void MemoryCacheGetAndSetTests() { var services = new ServiceCollection(); services.AddLinFx() .AddDistributedMemoryCache(); var container = services.BuildServiceProvider(); var _cache = container.GetService(); var expected = 100; _cache.Set("key1", expected); var actual = _cache.Get("key1"); Assert.Equal(expected, actual); } } } ```