ShopFx.Module.Devices

Package Description


Keywords
csharp, domain-driven-design, linfx
License
MIT
Install
Install-Package ShopFx.Module.Devices -Version 5.0.37

Documentation

LinFx

Build status GitHub license

一个基于 netstandard2.1 开发的简单易用的快速开发框架,遵循领域驱动设计(DDD)规范约束,提供实现事件驱动、事件回溯、响应式等特性的基础设施。让开发者享受到正真意义的面向对象设计模式来带的美感。


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)
  5. 框架中每个组件都有基础实现,最简单时只需一个核心类库就能跑起来
  6. 遵循端口与适配器模式,框架组件适配多种第三方组件实现,可从单体架构到面向服务架构按需扩展

知识点

  1. 领域驱动设计(Domain Driven Design (Layers and Domain Model Pattern)
  2. 命令查询职责分离(CQRS:Command Query Responsibility Segregation)
  3. 领域通知 (Domain Notification)
  4. 领域驱动 (Domain Events)
  5. 事件驱动架构 (EDA)
  6. 事件回溯 (Event Sourcing)
  7. 最终一致性 (Eventually Consistent)
  8. 工作单元模式 (Unit of Work )
  9. 泛型仓储 (Repository and Generic Repository)

设计规范

  1. 尽量使用.NET Standard和官方提供的类库,第三方类库设计成组件利用DI来按需组合。

安装Nuget包

PM> Install-Package LinFx

开发环境

  1. Visual Studio 15.3+
  2. .NET Core SDK 2.2+

Samples

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

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<OrderStatusChangedToAwaitingValidationIntegrationEventHandler>();
            //services.AddTransient<OrderStatusChangedToPaidIntegrationEventHandler>();

            var applicationServices = services.BuildServiceProvider();

            //ConfigureEventBus
            _eventBus = applicationServices.GetRequiredService<IEventBus>();
            _eventBus.Subscribe<OrderStatusChangedToAwaitingValidationIntegrationEvent, OrderStatusChangedToAwaitingValidationIntegrationEventHandler>();
            //eventBus.Subscribe<OrderStatusChangedToPaidIntegrationEvent, OrderStatusChangedToPaidIntegrationEventHandler>();
        }


        [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<OrderStockItem>
            {
            });
            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

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<IDistributedCache>();
        }

        [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

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<IMemoryCache>();

            var expected = 100;
            _cache.Set("key1", expected);
            var actual = _cache.Get("key1");

            Assert.Equal(expected, actual);
        }
    }
}