Building micro services through Event Driven Architecture part20 : Shared Libraries
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
Publish Packages
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