Building micro services through Event Driven Architecture part20 : Shared Libraries
This tutorial is the 20th part of a series : Building microservices through Event Driven Architecture.
The previous step is about Building micro services through Event Driven Architecture part19 : Building and Securing Real Time Communications using SignalR and Azure Active
A microservice architecture structures an application as a set of loosely coupled services.
An real advantage is that when there is a critical need to update a resource, only the microservice containing this resource will be updated, the other microservices remaining compatible with the modification, unlike the entire application in a classic architecture.
But what about shared code ?
Because I do not want to code the same functionality several times , I can follow the DRY principle ( Don’t Repeat Yourself) : “Every piece of knowledge must have a single, unambiguous, authoritative representation within a system” https://en.wikipedia.org/wiki/Don%27t_repeat_yourself
But when following DDD (Domain Driven Design) , The DRY principle is about domain knowledge and code duplication may be perfectly fine.
For those unfamiliar with DDD (Domain Driven Design), I recommend learning the basics. https://martinfowler.com/bliki/DomainDrivenDesign.html
In this tutorial, I will not discuss about the pros and cons of code sharing between micro services, but I will show to share code efficiently between microservices when needed. I will not share business functionnalites between microservices but only technical libraries like logging/monitoring, helpers, tools, etc…
I will use the versioning package following the semver principle https://semver.org/spec/v1.0.0.html.
This way, when code common to the microservice is updated, the version must be incremented and the package published in a nuget server.
So microservices can use the new version of the package only when needed and independently.
Packaging and Versionning
To package a Library, I have to open the project properties and check GeneratePackageOnBuild, and fill the properties accordingly as shown in the following figure :
I can also edit the LogCorner.EduSync.Speech.SharedKernel.csproj
<PropertyGroup> <TargetFramework>netstandard2.1</TargetFramework> <GeneratePackageOnBuild>true</GeneratePackageOnBuild> <AssemblyVersion>2.0.1</AssemblyVersion> <Version>2.0.1</Version> <PackageLicenseExpression>MIT</PackageLicenseExpression> <Copyright>LogCorner</Copyright> <PackageRequireLicenseAcceptance>True</PackageRequireLicenseAcceptance> <FileVersion>2.0.1</FileVersion> <PackageProjectUrl>https://logcorner.com/</PackageProjectUrl> <RepositoryUrl>https://github.com/logcorner/LogCorner.EduSync.Speech.Command/tree/master/src/LogCorner.EduSync.Speech.SharedKernel</RepositoryUrl> <EnforceCodeStyleInBuild>False</EnforceCodeStyleInBuild> <EnableNETAnalyzers>True</EnableNETAnalyzers> <AnalysisLevel>none</AnalysisLevel> <Title>The Speech Micro Service Command Shared Kernel</Title> <Company>Gora LEYE</Company> <Description>The Speech Micro Service Command Shared kernel contains a set of tools to serialize and deserialize events</Description> <PackageIcon>logcorner.png</PackageIcon> <PackageReadmeFile>README.md</PackageReadmeFile> <PackageTags>cqrs;event driven;serialization;</PackageTags> <PackageReleaseNotes>update package metadata</PackageReleaseNotes> </PropertyGroup>
So every time, the project is build , a package should be generated, Now I have to pubish the package in the next step
To pubish the package to github, I have to create an account https://www.nuget.org/ and create an API Key as following
Because I will publish the package during the build process, I must create a service connection in azure devops (https://dev.azure.com/ ) and fill the FeedUrl and AoiKey accordingly.
The steps to create an azure devops pipemine are discussed here https://logcorner.com/building-microservices-through-event-driven-architecture-part12-continuous-integration/
Here is the final build configuration file
resources: repositories: - repository: self type: git ref: develop jobs: - job: Job_1 displayName: Agent job 1 pool: name: LOGCORNER-POOL steps: - checkout: self - task: DotNetCoreCLI@2 displayName: dotnet restore inputs: command: restore projects: '**/*.csproj' - task: DotNetCoreCLI@2 displayName: dotnet build inputs: projects: '**/*.csproj' - task: VSBuild@1 displayName: database build inputs: solution: '**\*.sqlproj' - task: DotNetCoreCLI@2 displayName: dotnet test inputs: command: test projects: '**/*Unit[Tt]ests/*.csproj' - task: DotNetCoreCLI@2 displayName: dotnet pack inputs: command: 'pack' packagesToPack: 'src/LogCorner.EduSync.Speech.SharedKernel/LogCorner.EduSync.Speech.SharedKernel.csproj' packDirectory: '$(Build.ArtifactStagingDirectory)/Nugets' nobuild: true versioningScheme: 'off' - task: NuGetCommand@2 displayName: NuGet push inputs: command: 'push' packagesToPush: '$(Build.ArtifactStagingDirectory)/Nugets/*.nupkg' nuGetFeedType: 'external' publishFeedCredentials: 'nuget.org' allowPackageConflicts: true continueOnError: true ...
When I update a shared library and push the code to the github repository , azure devops will trigger a build, pack and publish the package to nuget.org . As a result, a new version of the package is publicly available for demos but it should be private in a production scenario.
Code source is available here :
Thanks for reading, if you have any feedback, feel free to post it