diff --git a/.editorconfig b/.editorconfig
new file mode 100644
index 0000000..1801ec6
--- /dev/null
+++ b/.editorconfig
@@ -0,0 +1,32 @@
+[*.cs]
+
+# CS8618: When exiting the constructor, the non-nullable field must contain a non-null value. Please consider declaring as nullable。
+dotnet_diagnostic.CS8618.severity = none
+
+# top-most EditorConfig file
+root = true
+
+# Don't use tabs for indentation.
+[*]
+indent_style = space
+trim_trailing_whitespace = true
+guidelines = 140
+max_line_length = 140
+
+# Code files
+[*.{cs,csx,vb,vbx}]
+indent_size = 4
+insert_final_newline = true
+charset = utf-8
+
+# Xml project files
+[*.{csproj,vbproj,vcxproj,vcxproj.filters,proj,projitems,shproj}]
+indent_size = 2
+
+# Xml config files
+[*.{props,targets,ruleset,config,nuspec,resx,vsixmanifest,vsct,xml,stylecop}]
+indent_size = 2
+
+# JSON files
+[*.json]
+indent_size = 2
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..18a2b91
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,222 @@
+## Ignore Visual Studio temporary files, build results, and
+## files generated by popular Visual Studio add-ons.
+# User-specific files
+*.suo
+*.user
+*.userosscache
+*.sln.docstates
+# User-specific files (MonoDevelop/Xamarin Studio)
+*.userprefs
+# Build results
+[Dd]ebug/
+[Dd]ebugPublic/
+[Rr]elease/
+[Rr]eleases/
+x64/
+x86/
+bld/
+[Bb]in/
+[Oo]bj/
+[Ll]og/
+.vs/
+# Visual Studio 2015 cache/options directory
+# Uncomment if you have tasks that create the project's static files in wwwroot
+#wwwroot/
+# MSTest test Results
+[Tt]est[Rr]esult*/
+[Bb]uild[Ll]og.*
+# NUNIT
+*.VisualState.xml
+TestResult.xml
+# Build Results of an ATL Project
+[Dd]ebugPS/
+[Rr]eleasePS/
+dlldata.c
+# DNX
+project.lock.json
+project.fragment.lock.json
+artifacts/
+*_i.c
+*_p.c
+*_i.h
+*.ilk
+*.meta
+*.obj
+*.pch
+*.pdb
+*.pgc
+*.pgd
+*.rsp
+*.sbr
+*.tlb
+*.tli
+*.tlh
+*.tmp
+*.tmp_proj
+*.log
+*.vspscc
+*.vssscc
+.builds
+*.pidb
+*.svclog
+*.scc
+*.exe
+*.bak
+# Chutzpah Test files
+_Chutzpah*
+# Visual C++ cache files
+ipch/
+*.aps
+*.ncb
+*.opendb
+*.opensdf
+*.sdf
+*.cachefile
+*.cache
+*.VC.db
+*.VC.VC.opendb
+# Visual Studio profiler
+*.psess
+*.vsp
+*.vspx
+*.sap
+# TFS 2012 Local Workspace
+$tf/
+# Guidance Automation Toolkit
+*.gpState
+# ReSharper is a .NET coding add-in
+_ReSharper*/
+*.[Rr]e[Ss]harper
+*.DotSettings.user
+# JustCode is a .NET coding add-in
+.JustCode
+# TeamCity is a build add-in
+_TeamCity*
+# DotCover is a Code Coverage Tool
+*.dotCover
+# NCrunch
+_NCrunch_*
+.*crunch*.local.xml
+nCrunchTemp_*
+# MightyMoose
+*.mm.*
+AutoTest.Net/
+# Web workbench (sass)
+.sass-cache/
+# Installshield output folder
+[Ee]xpress/
+# DocProject is a documentation generator add-in
+DocProject/buildhelp/
+DocProject/Help/*.HxT
+DocProject/Help/*.HxC
+DocProject/Help/*.hhc
+DocProject/Help/*.hhk
+DocProject/Help/*.hhp
+DocProject/Help/Html2
+DocProject/Help/html
+# Click-Once directory
+publish/
+# Publish Web Output
+*.[Pp]ublish.xml
+*.azurePubxml
+# TODO: Comment the next line if you want to checkin your web deploy settings
+# but database connection strings (with potential passwords) will be unencrypted
+#*.pubxml
+*.publishproj
+# Microsoft Azure Web App publish settings. Comment the next line if you want to
+# checkin your Azure Web App publish settings, but sensitive information contained
+# in these scripts will be unencrypted
+PublishScripts/
+# NuGet Packages
+*.nupkg
+# The packages folder can be ignored because of Package Restore
+**/packages/*
+# except build/, which is used as an MSBuild target.
+!**/packages/build/
+# Uncomment if necessary however generally it will be regenerated when needed
+#!**/packages/repositories.config
+# NuGet v3's project.json files produces more ignoreable files
+*.nuget.props
+*.nuget.targets
+# Microsoft Azure Build Output
+csx/
+*.build.csdef
+# Microsoft Azure Emulator
+ecf/
+rcf/
+# Windows Store app package directories and files
+AppPackages/
+BundleArtifacts/
+Package.StoreAssociation.xml
+_pkginfo.txt
+# Visual Studio cache files
+# files ending in .cache can be ignored
+*.[Cc]ache
+# but keep track of directories ending in .cache
+!*.[Cc]ache/
+# Others
+ClientBin/
+~$*
+*~
+*.dbmdl
+*.dbproj.schemaview
+*.jfm
+*.pfx
+*.publishsettings
+node_modules/
+orleans.codegen.cs
+# Since there are multiple workflows, uncomment next line to ignore bower_components
+# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
+#bower_components/
+# RIA/Silverlight projects
+Generated_Code/
+# Backup & report files from converting an old project file
+# to a newer Visual Studio version. Backup files are not needed,
+# because we have git ;-)
+_UpgradeReport_Files/
+Backup*/
+UpgradeLog*.XML
+UpgradeLog*.htm
+# SQL Server files
+*.mdf
+*.ldf
+# Business Intelligence projects
+*.rdl.data
+*.bim.layout
+*.bim_*.settings
+# Microsoft Fakes
+FakesAssemblies/
+# GhostDoc plugin setting file
+*.GhostDoc.xml
+# Node.js Tools for Visual Studio
+.ntvs_analysis.dat
+# Visual Studio 6 build log
+*.plg
+# Visual Studio 6 workspace options file
+*.opt
+# Visual Studio LightSwitch build output
+**/*.HTMLClient/GeneratedArtifacts
+**/*.DesktopClient/GeneratedArtifacts
+**/*.DesktopClient/ModelManifest.xml
+**/*.Server/GeneratedArtifacts
+**/*.Server/ModelManifest.xml
+_Pvt_Extensions
+# Paket dependency manager
+.paket/paket.exe
+paket-files/
+# FAKE - F# Make
+.fake/
+# JetBrains Rider
+.idea/
+*.sln.iml
+# CodeRush
+.cr/
+# Python Tools for Visual Studio (PTVS)
+__pycache__/
+*.pyc
+package-lock.json
+# 忽略windows生成的缩略图文件
+Thunbs.db
+#忽略nuget库
+packages/
+.vscode/
\ No newline at end of file
diff --git a/.vs/MASA.BuildingBlocks/DesignTimeBuild/.dtbcache.v2 b/.vs/MASA.BuildingBlocks/DesignTimeBuild/.dtbcache.v2
deleted file mode 100644
index 56f0e17..0000000
Binary files a/.vs/MASA.BuildingBlocks/DesignTimeBuild/.dtbcache.v2 and /dev/null differ
diff --git a/.vs/MASA.BuildingBlocks/v17/.futdcache.v1 b/.vs/MASA.BuildingBlocks/v17/.futdcache.v1
deleted file mode 100644
index 06455aa..0000000
Binary files a/.vs/MASA.BuildingBlocks/v17/.futdcache.v1 and /dev/null differ
diff --git a/.vs/MASA.BuildingBlocks/v17/.suo b/.vs/MASA.BuildingBlocks/v17/.suo
deleted file mode 100644
index 29d4cd3..0000000
Binary files a/.vs/MASA.BuildingBlocks/v17/.suo and /dev/null differ
diff --git a/Directory.Build.props b/Directory.Build.props
new file mode 100644
index 0000000..5e44171
--- /dev/null
+++ b/Directory.Build.props
@@ -0,0 +1,24 @@
+
+
+ $(AssemblyName)
+ packageIcon.png
+ masastack
+ © masastack Corporation. All rights reserved.
+ packageIcon.png
+ https://github.com/masastack/Masa.BuildingBlocks
+ git
+ true
+ $(MSBuildThisFileDirectory)
+ LICENSE.txt
+
+
+
+ True
+
+
+
+ True
+
+
+
+
diff --git a/LICENSE.txt b/LICENSE.txt
new file mode 100644
index 0000000..3f96be7
--- /dev/null
+++ b/LICENSE.txt
@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (c) MASA Stack
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
\ No newline at end of file
diff --git a/Masa.BuildingBlocks.sln b/Masa.BuildingBlocks.sln
new file mode 100644
index 0000000..c198518
--- /dev/null
+++ b/Masa.BuildingBlocks.sln
@@ -0,0 +1,150 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio Version 17
+VisualStudioVersion = 17.0.31521.260
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "BasicAbility", "BasicAbility", "{5DFAF4A2-ECB5-46E4-904D-1EA5F48B2D48}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Dispatcher", "Dispatcher", "{FBD326D3-E59C-433E-A88E-14E179E3093D}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "I18n", "I18n", "{EA2668AF-28E3-42C5-9FA5-8C9FF377180E}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Isolation", "Isolation", "{022D6FF5-4B65-4213-9A97-C69E2B2F99E1}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Observability", "Observability", "{75050CBC-A0F2-408A-A582-54EF37450B29}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "ReadWriteSpliting", "ReadWriteSpliting", "{509BDB5A-5D32-478F-BF27-F0470C18C7C9}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "SearchEngine", "SearchEngine", "{8C39C640-0E8A-43A7-890C-9742B6B70AA4}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Service", "Service", "{593A3114-D1E0-47ED-BC37-58E08886175B}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Testable", "Testable", "{57AD498B-D9AF-4479-8C14-45507F6509F5}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "DDD", "DDD", "{9CB643CA-AA09-46E7-8CB9-E1D55E84B32B}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Data", "Data", "{64FB8703-E922-45DE-9D01-3FE9EFE56727}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{77D17E30-CB7C-4DD7-8CF1-9D5350FF2304}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "test", "test", "{6ED365E6-4A1A-499F-85FB-F22E865CA4BA}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "design", "design", "{43157B67-5CDB-4D28-9095-9586C685CA6B}"
+ ProjectSection(SolutionItems) = preProject
+ design\CodeMap.dgml = design\CodeMap.dgml
+ EndProjectSection
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Configuration", "Configuration", "{884D1A0A-A24F-4ED9-BBFE-DCC4E47CF26D}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Masa.BuildingBlocks.Service.MinimalAPIs", "src\Service\Masa.BuildingBlocks.Service.MinimalAPIs\Masa.BuildingBlocks.Service.MinimalAPIs.csproj", "{F128E74B-CEC4-4915-AEE2-FF69E60D17F0}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Masa.BuildingBlocks.SearchEngine.AutoComplete", "src\SearchEngine\Masa.BuildingBlocks.SearchEngine.AutoComplete\Masa.BuildingBlocks.SearchEngine.AutoComplete.csproj", "{9782B9B5-22D0-432A-9BC5-D830C9478D38}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Masa.BuildingBlocks.ReadWriteSpliting.CQRS", "src\ReadWriteSpliting\Masa.BuildingBlocks.ReadWriteSpliting.CQRS\Masa.BuildingBlocks.ReadWriteSpliting.CQRS.csproj", "{8DAC72C3-FB8B-4F9B-AC44-F98CC665CB0C}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Masa.BuildingBlocks.ReadWriteSpliting.EventSourcing", "src\ReadWriteSpliting\Masa.BuildingBlocks.ReadWriteSpliting.EventSourcing\Masa.BuildingBlocks.ReadWriteSpliting.EventSourcing.csproj", "{6175D1D5-8007-4951-BF12-0064B8201C35}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Masa.BuildingBlocks.Dispatcher.Events", "src\Dispatcher\Masa.BuildingBlocks.Dispatcher.Events\Masa.BuildingBlocks.Dispatcher.Events.csproj", "{EECA2E9C-36B4-4DCE-93F7-487955B6260E}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Masa.BuildingBlocks.Dispatcher.IntegrationEvents", "src\Dispatcher\Masa.BuildingBlocks.Dispatcher.IntegrationEvents\Masa.BuildingBlocks.Dispatcher.IntegrationEvents.csproj", "{4A2ECF39-8999-4C18-83D4-6587A1D9D9EE}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Masa.BuildingBlocks.DDD.Domain", "src\DDD\Masa.BuildingBlocks.DDD.Domain\Masa.BuildingBlocks.DDD.Domain.csproj", "{D672874A-B848-4561-8D0C-11B58B7F308B}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Masa.BuildingBlocks.Data.Contracts", "src\Data\Masa.BuildingBlocks.Data.Contracts\Masa.BuildingBlocks.Data.Contracts.csproj", "{B735824E-D918-4140-AE94-CA4172BF59EB}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Masa.BuildingBlocks.Data.UoW", "src\Data\Masa.BuildingBlocks.Data.UoW\Masa.BuildingBlocks.Data.UoW.csproj", "{41F94385-3EAC-4617-8C2B-74D606B0A6A6}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Masa.BuildingBlocks.Configuration", "src\Configuration\Masa.BuildingBlocks.Configuration\Masa.BuildingBlocks.Configuration.csproj", "{E86483C1-1479-453A-8ABC-35DAC95AC056}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Masa.BuildingBlocks.Configuration.Tests", "test\Masa.BuildingBlocks.Configuration.Tests\Masa.BuildingBlocks.Configuration.Tests.csproj", "{E7F59F98-3D2A-46BC-83FC-CB66A8D1041C}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Masa.BuildingBlocks.DDD.Domain.Tests", "test\Masa.BuildingBlocks.DDD.Domain.Tests\Masa.BuildingBlocks.DDD.Domain.Tests.csproj", "{5791FF31-6579-46D6-8E65-48031C947B7D}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Release|Any CPU = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {F128E74B-CEC4-4915-AEE2-FF69E60D17F0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {F128E74B-CEC4-4915-AEE2-FF69E60D17F0}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {F128E74B-CEC4-4915-AEE2-FF69E60D17F0}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {F128E74B-CEC4-4915-AEE2-FF69E60D17F0}.Release|Any CPU.Build.0 = Release|Any CPU
+ {9782B9B5-22D0-432A-9BC5-D830C9478D38}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {9782B9B5-22D0-432A-9BC5-D830C9478D38}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {9782B9B5-22D0-432A-9BC5-D830C9478D38}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {9782B9B5-22D0-432A-9BC5-D830C9478D38}.Release|Any CPU.Build.0 = Release|Any CPU
+ {8DAC72C3-FB8B-4F9B-AC44-F98CC665CB0C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {8DAC72C3-FB8B-4F9B-AC44-F98CC665CB0C}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {8DAC72C3-FB8B-4F9B-AC44-F98CC665CB0C}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {8DAC72C3-FB8B-4F9B-AC44-F98CC665CB0C}.Release|Any CPU.Build.0 = Release|Any CPU
+ {6175D1D5-8007-4951-BF12-0064B8201C35}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {6175D1D5-8007-4951-BF12-0064B8201C35}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {6175D1D5-8007-4951-BF12-0064B8201C35}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {6175D1D5-8007-4951-BF12-0064B8201C35}.Release|Any CPU.Build.0 = Release|Any CPU
+ {EECA2E9C-36B4-4DCE-93F7-487955B6260E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {EECA2E9C-36B4-4DCE-93F7-487955B6260E}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {EECA2E9C-36B4-4DCE-93F7-487955B6260E}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {EECA2E9C-36B4-4DCE-93F7-487955B6260E}.Release|Any CPU.Build.0 = Release|Any CPU
+ {4A2ECF39-8999-4C18-83D4-6587A1D9D9EE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {4A2ECF39-8999-4C18-83D4-6587A1D9D9EE}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {4A2ECF39-8999-4C18-83D4-6587A1D9D9EE}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {4A2ECF39-8999-4C18-83D4-6587A1D9D9EE}.Release|Any CPU.Build.0 = Release|Any CPU
+ {D672874A-B848-4561-8D0C-11B58B7F308B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {D672874A-B848-4561-8D0C-11B58B7F308B}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {D672874A-B848-4561-8D0C-11B58B7F308B}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {D672874A-B848-4561-8D0C-11B58B7F308B}.Release|Any CPU.Build.0 = Release|Any CPU
+ {B735824E-D918-4140-AE94-CA4172BF59EB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {B735824E-D918-4140-AE94-CA4172BF59EB}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {B735824E-D918-4140-AE94-CA4172BF59EB}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {B735824E-D918-4140-AE94-CA4172BF59EB}.Release|Any CPU.Build.0 = Release|Any CPU
+ {41F94385-3EAC-4617-8C2B-74D606B0A6A6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {41F94385-3EAC-4617-8C2B-74D606B0A6A6}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {41F94385-3EAC-4617-8C2B-74D606B0A6A6}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {41F94385-3EAC-4617-8C2B-74D606B0A6A6}.Release|Any CPU.Build.0 = Release|Any CPU
+ {E86483C1-1479-453A-8ABC-35DAC95AC056}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {E86483C1-1479-453A-8ABC-35DAC95AC056}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {E86483C1-1479-453A-8ABC-35DAC95AC056}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {E86483C1-1479-453A-8ABC-35DAC95AC056}.Release|Any CPU.Build.0 = Release|Any CPU
+ {E7F59F98-3D2A-46BC-83FC-CB66A8D1041C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {E7F59F98-3D2A-46BC-83FC-CB66A8D1041C}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {E7F59F98-3D2A-46BC-83FC-CB66A8D1041C}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {E7F59F98-3D2A-46BC-83FC-CB66A8D1041C}.Release|Any CPU.Build.0 = Release|Any CPU
+ {5791FF31-6579-46D6-8E65-48031C947B7D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {5791FF31-6579-46D6-8E65-48031C947B7D}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {5791FF31-6579-46D6-8E65-48031C947B7D}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {5791FF31-6579-46D6-8E65-48031C947B7D}.Release|Any CPU.Build.0 = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+ GlobalSection(NestedProjects) = preSolution
+ {5DFAF4A2-ECB5-46E4-904D-1EA5F48B2D48} = {77D17E30-CB7C-4DD7-8CF1-9D5350FF2304}
+ {FBD326D3-E59C-433E-A88E-14E179E3093D} = {77D17E30-CB7C-4DD7-8CF1-9D5350FF2304}
+ {EA2668AF-28E3-42C5-9FA5-8C9FF377180E} = {77D17E30-CB7C-4DD7-8CF1-9D5350FF2304}
+ {022D6FF5-4B65-4213-9A97-C69E2B2F99E1} = {77D17E30-CB7C-4DD7-8CF1-9D5350FF2304}
+ {75050CBC-A0F2-408A-A582-54EF37450B29} = {77D17E30-CB7C-4DD7-8CF1-9D5350FF2304}
+ {509BDB5A-5D32-478F-BF27-F0470C18C7C9} = {77D17E30-CB7C-4DD7-8CF1-9D5350FF2304}
+ {8C39C640-0E8A-43A7-890C-9742B6B70AA4} = {77D17E30-CB7C-4DD7-8CF1-9D5350FF2304}
+ {593A3114-D1E0-47ED-BC37-58E08886175B} = {77D17E30-CB7C-4DD7-8CF1-9D5350FF2304}
+ {57AD498B-D9AF-4479-8C14-45507F6509F5} = {77D17E30-CB7C-4DD7-8CF1-9D5350FF2304}
+ {9CB643CA-AA09-46E7-8CB9-E1D55E84B32B} = {77D17E30-CB7C-4DD7-8CF1-9D5350FF2304}
+ {64FB8703-E922-45DE-9D01-3FE9EFE56727} = {77D17E30-CB7C-4DD7-8CF1-9D5350FF2304}
+ {884D1A0A-A24F-4ED9-BBFE-DCC4E47CF26D} = {77D17E30-CB7C-4DD7-8CF1-9D5350FF2304}
+ {F128E74B-CEC4-4915-AEE2-FF69E60D17F0} = {593A3114-D1E0-47ED-BC37-58E08886175B}
+ {9782B9B5-22D0-432A-9BC5-D830C9478D38} = {8C39C640-0E8A-43A7-890C-9742B6B70AA4}
+ {8DAC72C3-FB8B-4F9B-AC44-F98CC665CB0C} = {509BDB5A-5D32-478F-BF27-F0470C18C7C9}
+ {6175D1D5-8007-4951-BF12-0064B8201C35} = {509BDB5A-5D32-478F-BF27-F0470C18C7C9}
+ {EECA2E9C-36B4-4DCE-93F7-487955B6260E} = {FBD326D3-E59C-433E-A88E-14E179E3093D}
+ {4A2ECF39-8999-4C18-83D4-6587A1D9D9EE} = {FBD326D3-E59C-433E-A88E-14E179E3093D}
+ {D672874A-B848-4561-8D0C-11B58B7F308B} = {9CB643CA-AA09-46E7-8CB9-E1D55E84B32B}
+ {B735824E-D918-4140-AE94-CA4172BF59EB} = {64FB8703-E922-45DE-9D01-3FE9EFE56727}
+ {41F94385-3EAC-4617-8C2B-74D606B0A6A6} = {64FB8703-E922-45DE-9D01-3FE9EFE56727}
+ {E86483C1-1479-453A-8ABC-35DAC95AC056} = {884D1A0A-A24F-4ED9-BBFE-DCC4E47CF26D}
+ {E7F59F98-3D2A-46BC-83FC-CB66A8D1041C} = {6ED365E6-4A1A-499F-85FB-F22E865CA4BA}
+ {5791FF31-6579-46D6-8E65-48031C947B7D} = {6ED365E6-4A1A-499F-85FB-F22E865CA4BA}
+ EndGlobalSection
+ GlobalSection(ExtensibilityGlobals) = postSolution
+ SolutionGuid = {40383055-CC50-4600-AD9A-53C14F620D03}
+ EndGlobalSection
+EndGlobal
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..cb23998
--- /dev/null
+++ b/README.md
@@ -0,0 +1,3 @@
+[中](README.zh-CN.md) | EN
+# Masa.BuildingBlocks
+Building blocks of the MASA Stack, provides a unified interface standard for MASA Contrib's implementation specifications and process connector.
diff --git a/README.zh-CN.md b/README.zh-CN.md
new file mode 100644
index 0000000..f2f7631
--- /dev/null
+++ b/README.zh-CN.md
@@ -0,0 +1,3 @@
+中 | [EN](README.md)
+# Masa.BuildingBlocks
+MASA Stack的构建块,提供统一的接口标准,用于MASA Contrib的实现规约和流程衔接。
diff --git a/design/CodeMap.dgml b/design/CodeMap.dgml
new file mode 100644
index 0000000..39224de
--- /dev/null
+++ b/design/CodeMap.dgml
@@ -0,0 +1,473 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/nuget.config b/nuget.config
new file mode 100644
index 0000000..4f27eb2
--- /dev/null
+++ b/nuget.config
@@ -0,0 +1,6 @@
+
+
+
+
+
+
diff --git a/packageIcon.png b/packageIcon.png
new file mode 100644
index 0000000..2128805
Binary files /dev/null and b/packageIcon.png differ
diff --git a/src/Configuration/Masa.BuildingBlocks.Configuration/AbstractConfigurationRepository.cs b/src/Configuration/Masa.BuildingBlocks.Configuration/AbstractConfigurationRepository.cs
new file mode 100644
index 0000000..dea1259
--- /dev/null
+++ b/src/Configuration/Masa.BuildingBlocks.Configuration/AbstractConfigurationRepository.cs
@@ -0,0 +1,39 @@
+namespace Masa.BuildingBlocks.Configuration;
+
+public abstract class AbstractConfigurationRepository : IConfigurationRepository
+{
+ private readonly ILogger? _logger;
+
+ private readonly List _listeners = new();
+
+ public abstract SectionTypes SectionType { get; init; }
+
+ public AbstractConfigurationRepository(ILoggerFactory? loggerFactory = null)
+ => _logger = loggerFactory?.CreateLogger();
+
+ public abstract Properties Load();
+
+ public void AddChangeListener(IRepositoryChangeListener listener)
+ {
+ if (!_listeners.Contains(listener))
+ _listeners.Add(listener);
+ }
+
+ public void RemoveChangeListener(IRepositoryChangeListener listener)
+ => _listeners.Remove(listener);
+
+ public void FireRepositoryChange(SectionTypes sectionType, Properties newProperties)
+ {
+ foreach (var listener in _listeners)
+ {
+ try
+ {
+ listener.OnRepositoryChange(sectionType, newProperties);
+ }
+ catch (Exception ex)
+ {
+ _logger?.LogError($"Failed to invoke repository change listener {listener.GetType()}", ex);
+ }
+ }
+ }
+}
diff --git a/src/Configuration/Masa.BuildingBlocks.Configuration/ConfigurationTypes.cs b/src/Configuration/Masa.BuildingBlocks.Configuration/ConfigurationTypes.cs
new file mode 100644
index 0000000..09f64b1
--- /dev/null
+++ b/src/Configuration/Masa.BuildingBlocks.Configuration/ConfigurationTypes.cs
@@ -0,0 +1,9 @@
+namespace Masa.BuildingBlocks.Configuration;
+public enum ConfigurationTypes
+{
+ Properties = 1,
+ Text,
+ Json,
+ Yaml,
+ Xml
+}
diff --git a/src/Configuration/Masa.BuildingBlocks.Configuration/IConfigurationApiClient.cs b/src/Configuration/Masa.BuildingBlocks.Configuration/IConfigurationApiClient.cs
new file mode 100644
index 0000000..3a7343e
--- /dev/null
+++ b/src/Configuration/Masa.BuildingBlocks.Configuration/IConfigurationApiClient.cs
@@ -0,0 +1,12 @@
+namespace Masa.BuildingBlocks.Configuration;
+public interface IConfigurationApiClient
+{
+ Task<(string Raw, ConfigurationTypes ConfigurationType)> GetRawAsync(string environment, string cluster, string appId, string configObject, Action valueChanged);
+
+ Task GetAsync(string environment, string cluster, string appId, string configObject, Action valueChanged);
+
+ Task GetDynamicAsync(string environment, string cluster, string appId, string configObject, Action valueChanged);
+
+ Task GetDynamicAsync(string key);
+}
+
diff --git a/src/Configuration/Masa.BuildingBlocks.Configuration/IConfigurationApiManage.cs b/src/Configuration/Masa.BuildingBlocks.Configuration/IConfigurationApiManage.cs
new file mode 100644
index 0000000..f95c529
--- /dev/null
+++ b/src/Configuration/Masa.BuildingBlocks.Configuration/IConfigurationApiManage.cs
@@ -0,0 +1,5 @@
+namespace Masa.BuildingBlocks.Configuration;
+public interface IConfigurationApiManage
+{
+ Task UpdateAsync(string environment, string cluster, string appId, string configObject, object value);
+}
diff --git a/src/Configuration/Masa.BuildingBlocks.Configuration/IConfigurationRepository.cs b/src/Configuration/Masa.BuildingBlocks.Configuration/IConfigurationRepository.cs
new file mode 100644
index 0000000..d363fd2
--- /dev/null
+++ b/src/Configuration/Masa.BuildingBlocks.Configuration/IConfigurationRepository.cs
@@ -0,0 +1,11 @@
+namespace Masa.BuildingBlocks.Configuration;
+public interface IConfigurationRepository
+{
+ SectionTypes SectionType { get; init; }
+
+ Properties Load();
+
+ void AddChangeListener(IRepositoryChangeListener listener);
+
+ void RemoveChangeListener(IRepositoryChangeListener listener);
+}
diff --git a/src/Configuration/Masa.BuildingBlocks.Configuration/IMasaConfigurationBuilder.cs b/src/Configuration/Masa.BuildingBlocks.Configuration/IMasaConfigurationBuilder.cs
new file mode 100644
index 0000000..1cf192b
--- /dev/null
+++ b/src/Configuration/Masa.BuildingBlocks.Configuration/IMasaConfigurationBuilder.cs
@@ -0,0 +1,16 @@
+namespace Masa.BuildingBlocks.Configuration;
+public interface IMasaConfigurationBuilder : IConfigurationBuilder
+{
+ Dictionary GetSectionRelations();
+
+ ///
+ /// Mount node information
+ ///
+ ///
+ /// The default is the root node
+ void AddSection(IConfigurationBuilder configurationBuilder, string? sectionName = null);
+
+ void AddRepository(IConfigurationRepository configurationRepository);
+
+ void AddRelations(params ConfigurationRelationOptions[] relationOptions);
+}
diff --git a/src/Configuration/Masa.BuildingBlocks.Configuration/IRepositoryChangeListener.cs b/src/Configuration/Masa.BuildingBlocks.Configuration/IRepositoryChangeListener.cs
new file mode 100644
index 0000000..ed7a70f
--- /dev/null
+++ b/src/Configuration/Masa.BuildingBlocks.Configuration/IRepositoryChangeListener.cs
@@ -0,0 +1,5 @@
+namespace Masa.BuildingBlocks.Configuration;
+public interface IRepositoryChangeListener
+{
+ void OnRepositoryChange(SectionTypes sectionType, Properties newProperties);
+}
diff --git a/src/Configuration/Masa.BuildingBlocks.Configuration/Masa.BuildingBlocks.Configuration.csproj b/src/Configuration/Masa.BuildingBlocks.Configuration/Masa.BuildingBlocks.Configuration.csproj
new file mode 100644
index 0000000..406a26a
--- /dev/null
+++ b/src/Configuration/Masa.BuildingBlocks.Configuration/Masa.BuildingBlocks.Configuration.csproj
@@ -0,0 +1,14 @@
+
+
+
+ net6.0
+ enable
+ enable
+
+
+
+
+
+
+
+
diff --git a/src/Configuration/Masa.BuildingBlocks.Configuration/Options/ConfigurationRelationOptions.cs b/src/Configuration/Masa.BuildingBlocks.Configuration/Options/ConfigurationRelationOptions.cs
new file mode 100644
index 0000000..f0cfb9f
--- /dev/null
+++ b/src/Configuration/Masa.BuildingBlocks.Configuration/Options/ConfigurationRelationOptions.cs
@@ -0,0 +1,14 @@
+namespace Masa.BuildingBlocks.Configuration.Options;
+public class ConfigurationRelationOptions
+{
+ public SectionTypes SectionType { get; set; }
+
+ public string? ParentSection { get; set; }
+
+ public string Section { get; set; } = default!;
+
+ ///
+ /// Object type of mapping node relationship
+ ///
+ public Type ObjectType { get; set; } = default!;
+}
diff --git a/src/Configuration/Masa.BuildingBlocks.Configuration/Options/IMasaConfigurationOptions.cs b/src/Configuration/Masa.BuildingBlocks.Configuration/Options/IMasaConfigurationOptions.cs
new file mode 100644
index 0000000..1988c87
--- /dev/null
+++ b/src/Configuration/Masa.BuildingBlocks.Configuration/Options/IMasaConfigurationOptions.cs
@@ -0,0 +1,21 @@
+namespace Masa.BuildingBlocks.Configuration.Options;
+///
+/// Automatic mapping relationship specification.
+/// When RootSection is Null or an empty string, the configuration will be mounted to the root node.
+/// When Section is Null, the configuration will be mounted under the RootSection node, and its node name is class name.
+/// If Section is an empty string, it will be directly mounted under the RootSection node
+///
+public interface IMasaConfigurationOptions
+{
+ [JsonIgnore]
+ string? ParentSection { get; init; }
+
+ ///
+ /// Node name, adjust the mapping relationship by modifying the node name
+ ///
+ [JsonIgnore]
+ string? Section { get; init; }
+
+ [JsonIgnore]
+ SectionTypes SectionType { get; init; }
+}
diff --git a/src/Configuration/Masa.BuildingBlocks.Configuration/Properties.cs b/src/Configuration/Masa.BuildingBlocks.Configuration/Properties.cs
new file mode 100644
index 0000000..ac18f6d
--- /dev/null
+++ b/src/Configuration/Masa.BuildingBlocks.Configuration/Properties.cs
@@ -0,0 +1,69 @@
+namespace Masa.BuildingBlocks.Configuration;
+public class Properties : IEquatable, IEquatable