Upgrading

Update the Beamable CLI and workspaces

Update the CLI

To install the latest version of the CLI, use the following command.

dotnet beam version install latest

You can also search for available versions with the beam version ls command. The beam version install command accepts any valid version instead of the "latest" string in the example above.

📘

.config/dotnet-tools.json

As of CLI 3.0.0, Standalone Microservice Projects use dotnet local tool installations for Beamable. The version number is stored in a special dotnet file, .config/dotnet-tools.json. This file should be committed to version control. Please do not edit this file directly, and prefer instead to use the beam version command suite.

Migration Guide

The Beamable CLI may include changes between versions that require developer intervention. If there are known steps that a developer must perform manually, they are documented below. The following sections describe the required updates from one version to another.

These are ordered with the latest versions towards the top, and the older versions toward the bottom of the document. When jumping multiple versions (A.A.A -> C.C.C), apply the migrations without skipping steps (A.A.A -> B.B.B -> C.C.C).

From 2.0.2 to 3.0.1

The upgrade from 2.0.x to 3.0.1 brings a few critical updates to the csproj file, how the Beam CLI tool is managed, and the version of dotnet.

To start this process, let's open a terminal and navigate to the directory containing your .beamable folder. All commands are written as though invoked from this directory.

# In this file structure...
SomeDrive
|---ProjectRoot
|---|--- .beamable

# You should make sure you're in the directory containing the .beamable folder
cd SomeDrive/ProjectRoot

CLI File Structure

Starting with CLI 3.0.1, you should start by updating the CLI's file structure. The steps required are defined below:

  1. Install dotnet 8 SDK in your machine (it is the new recommended version). The old net6.0 framework's end-of-life arrived on November 12, 2024.
  2. Delete the .beamable/local-services-manifest.json file. (It is no longer necessary)

Previous to 3.0.0, the CLI was always installed globally and all Beamable CLI projects on your computer had to share the same CLI version. You could un-install & re-install specific versions when switching projects, but that is a bad workflow --- so... we changed it.

In 3.0.0, the CLI should be installed as a local dotnet tool.

The steps to change your project from using the global CLI tool to a local dotnet tool are defined below.

Start by verifying you are in the correct location by running the following command.

cat .beamable/connection-configuration.json 
{
  "host": "https://api.beamable.com",
  "cid": "857238240682",
  "pid": "DE_58923576234234"
}

Next, run dotnet tool install --create-manifest-if-needed beamable.tools --version 3.0.1. This should create a file in a top level .config/dotnet-tools.json with the following contents.

{  
  "version": 1,  
  "isRoot": true,  
  "tools": {  
    "beamable.tools": {  
      "version": "3.0.1",  
      "commands": [  
        "beam"  
      ],  
      "rollForward": false  
    }  
  }}

Finally, to verify that the tool is installed locally, run the following,

dotnet beam version
 {                                                
    "version": "3.0.1",               
    "location": "/usr/local/share/dotnet/dotnet", 
    "type": "LocalTool",                          
    "templates": "3.0.1"
 }   

From here on out, if you want to use the project specific CLI run dotnet beam instead of beam.

However, if you run beam in the context of a local project and the global version of your CLI is different than the local project version, the command will be automatically forwarded to the local version. This does add some latency so prefer dotnet beam whenever you can.

You will see a warning message similar to this when invoking beam directly:

You tried using a Beamable CLI version=[3.0.1] which is different than the one configured in this project=[3.0.0-PREVIEW.RC2]. We are forwarding the command (beam 
--pretty version) to the version the project is using via dotnet=[dotnet]. Instead of relying on this forwarding, please 'dotnet beam' from inside the project directory.

Updating the .csproj Files

The next step in this migration is to fix up the .csproj files for your microservices. The new .csproj file structure comes with a few new things:

  • It will version-lock the package versions to the currently local CLI version (the one inside .config/dotnet-tools.json).
    • This means updating the CLI is just changing that version number.
    • You can manually edit this to dodge the version-lock if you want to risk it.
  • It includes a Roslyn Static Analyser to help you out with microservices and federation implementations.
  • It'll target .net8.

In every csproj file for Microservices, MicroStorages, and Common Libraries, follow the steps below:

First, add a PropertyGroup with a Label called Beamable Version that looks like this:

<!-- These are special Beamable parameters that we use to keep the beamable packages in-sync to the CLI version your project is using. -->  
<!-- This makes it so your microservices are auto-updated whenever you update the CLI installed in your project. -->  
<PropertyGroup Label="Beamable Version" Condition="$(DOTNET_RUNNING_IN_CONTAINER)!=true">  
  <DotNetConfigPath Condition="'$(DotNetConfigPath)' == ''">$([MSBuild]::GetDirectoryNameOfFileAbove("$(MSBuildProjectDirectory)/..", ".config/dotnet-tools.json"))</DotNetConfigPath>  
  <DotNetConfig Condition="'$(DotNetConfig)' == ''">$([System.IO.File]::ReadAllText("$(DotNetConfigPath)/.config/dotnet-tools.json"))</DotNetConfig>  
  <!-- Extracts the version number from the first tool defined in 'dotnet-tools.json' that starts with "beamable". -->  
  <BeamableVersion Condition="'$(BeamableVersion)' == ''">$([System.Text.RegularExpressions.Regex]::Match("$(DotNetConfig)", "beamable.*?\"([0-9]+\.[0-9]+\.[0-9]+.*?)\",", RegexOptions.Singleline | RegexOptions.IgnorePatternWhitespace).Groups[1].Value)</BeamableVersion>  
  <!-- When running from inside docker, this gets injected via the Dockerfile at build-time. -->  
</PropertyGroup>

Then, we recommend you upgrade the TargetFramework to .net8.0:

<PropertyGroup Label="Dotnet Settings">  
  <!-- net8.0 is the LTS version until 2026. To update your net version, update the <TargetFramework> when Beamable announces support. -->  
  <TargetFramework>net8.0</TargetFramework>  
</PropertyGroup>
Microservices

For every Microservice project replace all PackageReference elements that reference a Beamable. with the following two references:

<PackageReference Include="Beamable.Microservice.Runtime" Version="$(BeamableVersion)" />  
<PackageReference Include="Beamable.Microservice.SourceGen" Version="$(BeamableVersion)" OutputItemType="Analyzer" />  

Then, also add the following to the Beamable Settings Property Group:

<PropertyGroup Label="Beamable Settings">  
  <!-- All Microservices must have the value, "service" -->  
  <BeamProjectType>service</BeamProjectType>          
</PropertyGroup>
MicroStorages

For every MicroStorage project, replace all PackageReference elements that reference a Beamable. with the following reference:

<PackageReference Include="Beamable.Microservice.Runtime" Version="$(BeamableVersion)" />

Then, add the following to the Beamable Settings Property Group. Please replace MyStorage with your csproj's file name.

<BeamProjectType>storage</BeamProjectType>  
<!-- When the Storage Object is running locally in Docker, these volume names are used to persist data between container restart events. -->  
<MyStorageDockerDataVolume>beamable_storage_MyStorage_data</MyStorageDockerDataVolume>  
<MyStorageDockerFilesVolume>beamable_storage_MyStorage_files</MyStorageDockerFilesVolume>
Common Libraries

For every Common Library project, replace all PackageReference elements that reference a Beamable. with the following reference:

<PackageReference Include="Beamable.Microservice.Runtime" Version="$(BeamableVersion)" />

Then, also add the following to the Beamable Settings Property Group:

<PropertyGroup Label="Beamable Settings">  
  <!-- All Microservices must have the value, "service" -->  
  <BeamProjectType>service</BeamProjectType>          
</PropertyGroup>

Microservice Code Changes - partial and FederationId

With the introduction of the Beamable.Microservice.SourceGen library, all Microservice classes must be marked with the partial keyword. This will allow the source-generator to add custom implementations to Microservices in future releases.

If you use any Federated endpoints as part of your Microservices, there a few code-changes you'll have to make:

  • Replace all IThirdPartyCloudIdentity with IFederationId.
  • Add a FederationId attribute to the class IFederationId --- the UniqueName is the property.
  • If you were ever accessing the UniqueName property as part of your code, you'll need to replace those calls with GetUniqueName().

Once these are in, try to compile your services. The newly referenced Roslyn Static Analyzer should tell you if you made any mistakes.

Finally, the analyzer will inform you that the federations you have in code are not in the federation.json file. The error will look something like this:

Error BEAM_FED_O001 : Missing declared Federation in MicroserviceFederationsConfig. Microservice=SteamDemo, Id=steam, Interface=IFederatedLogin. Please add this Id by running `dotnet beam fed add SteamDemo steam IFederatedLogin` from your project's root directory. Or remove the IFederatedLogin that references steam  interface from the SteamDemo Microservice class.

You can run the command described in the error message to register the federation in the code with the federation.json file.

📘

Why is this needed?

We now support the ability to test federations locally (which was previously impossible due to architecture of 2.0.0). With this new ability, some UX requirements changed for our engine integrations. This change helps the development experience of such cases in the Unity/Unreal editor integrations.

Updating the Dockerfile Files

This is very simple: simply replace the contents of each Dockerfile with the following. After replacing it, you can re-add any previous modifications you might've had.

Make sure that the version in this line ARG BEAM_DOTNET_VERSION="8.0-alpine" matches the .net version in the .csproj file.

ARG BEAM_DOTNET_VERSION="8.0-alpine"  
FROM mcr.microsoft.com/dotnet/runtime:${BEAM_DOTNET_VERSION}  
  
# These args are provided by the Beam CLI  
  
# Declares the relative path from the beamable workspace to the pre-build support binaries for BeamService  
#  Normally, this will be /services/BeamService/bin/beamApp/support  
ARG BEAM_SUPPORT_SRC_PATH  
  
# Declares the relative path from the beamable workspace to the pre-built binaries for BeamService  
#  Normally, this will be /services/BeamService/bin/beamApp/app  
ARG BEAM_APP_SRC_PATH  
  
# Declares where the built application will exist inside the Docker image.  
#  This value is usually /beamApp/BeamService  
ARG BEAM_APP_DEST  
  
# <beamReserved> Beamable may inject custom settings into this Dockerfile. Please do not remove these lines. # </beamReserved>  
  
# /beamApp is the directory that will hold the application  
WORKDIR /beamApp  
  
# expose the health port  
EXPOSE 6565   
# copy general supporting files  
COPY $BEAM_SUPPORT_SRC_PATH .  
  
# copy specific application code  
COPY $BEAM_APP_SRC_PATH .  
  
# ensure that the application is runnable  
RUN chmod +x $BEAM_APP_DEST  
ENV BEAM_APP=$BEAM_APP_DEST  
  
# when starting the container, run dotnet with the built dll  
ENTRYPOINT "dotnet" $BEAM_APP  
  
# Swap entrypoints if the container is exploding and you want to keep it alive indefinitely so you can go look into it.  
#ENTRYPOINT ["tail", "-f", "/dev/null"]

From 1.19.22 to 2.0.1

CLI File Structure

The .beamable folder structure changes between the major versions 1, and 2.
After you upgrade your global CLI to 2.0.1, run the following command in your project. This command should automatically perform some of the required upgrade steps.

beam config

If you forgot to the run the command, or would like to verify that the upgrade happened correctly, follow the bullets below.

  • The .beamable/beamoLocalManifest.json file should no longer exist.
  • The .beamable/beamoLocalRuntime.json file should no longer exist.
  • The .beamable/config-defaults.json file should no longer exist.
  • The .beamable/user-token.json file should no longer exist.

Instead, you should expect to see (at least),

  • .beamable/connection-configuration.json (this replaces the old config-defaults file. )
  • .beamable/temp/connection-auth.json (this replaces the old user-token file)

.csproj Files

SDK Version

Unfortunately, the upgrade flow between major version 1 and 2 does not automatically upgrade the nuget dependency on Beamable. All of the .csproj files you may have will need to be manually upgraded to Beamable 2.0.1. Remember, every service, common library, and storage have their own .csproj files.

Open each csproj file, and find the <PackageReference> for Beamable.
For a service, it will likely look like this,

<PackageReference Include="Beamable.Microservice.Runtime" Version="1.19.22" />

For a storage, it may (unfortunately) look like this

<PackageReference Include="Beamable.Microservice.Runtime" Version="1.15.0-PREVIEW.RC1" />

And for a common library,

<PackageReference Include="Beamable.Common" Version="1.19.22" />

In all these cases, please update the Version to 2.0.1.

Structure

In addition, different project types have the following upgrade requirements...

Services

For services, the csproj file has been simplified between major versions 1 and 2. You can remove all of the tasks and extraneous nuget references.

This snippet can (and should) be removed from a 1.19.22 service's csproj file.

  
<PackageReference Include="EmbedIO" Version="3.4.*" />  
<PackageReference Include="LoxSmoke.DocXml" Version="3.4.*" />  
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="6.0.0-preview.6.21352.12" />  
<PackageReference Include="Microsoft.OpenApi" Version="1.6.3" />  
<PackageReference Include="Microsoft.OpenApi.Readers" Version="1.3.2" />  
<PackageReference Include="NetMQ" Version="4.0.1.11" />  
<PackageReference Include="Newtonsoft.Json" Version="13.0.*" />  
<PackageReference Include="Serilog" Version="2.10.*" />  
<PackageReference Include="Serilog.Formatting.Compact" Version="1.1.*" />  
<PackageReference Include="Serilog.Sinks.Console" Version="3.1.*" />  
<PackageReference Include="System.CommandLine" Version="2.0.0-beta3.22114.*" />  
<PackageReference Include="System.ServiceModel.Primitives" Version="4.9.*" />  
<PackageReference Include="System.Threading.RateLimiting" Version="7.0.0" />

Also, all of these targets can be removed,

  
<!-- After the build completes, we can open the local swagger page to make it easy to test endpoints -->  
<Target Name="open-swagger" AfterTargets="Build" Condition="$(OpenLocalSwaggerOnRun)==true AND $(DOTNET_RUNNING_IN_CONTAINER)!=true">  
    <Message Text="Opening local swagger docs..." Importance="high" />  
    <Exec Command="$(BeamableTool) project open-swagger $(AssemblyName)" />  
</Target>  
  
<!-- After the build completes, we should auto-generate client code to any linked projects -->  
<Target Name="generate-client" AfterTargets="Build" Condition="$(GenerateClientCode)==true AND $(DOTNET_RUNNING_IN_CONTAINER)!=true">  
    <Message Text="Generating client files..." Importance="high" />  
    <Exec Command="$(BeamableTool) project generate-client $(OutDir)/$(AssemblyName).dll --output-links" />  
</Target>  
  
<!-- Before starting the build, we need to prepare a few files and an .env file to pass startup information to the service -->  
<Target Name="setup-beamable" BeforeTargets="Build" DependsOnTargets="RunResolvePackageDependencies" Condition="$(DOTNET_RUNNING_IN_CONTAINER)!=true">  
  
    <PropertyGroup>        <BeamableVersion>@(BeamablePackage->'%(Version)')</BeamableVersion>  
    </PropertyGroup>    <!-- We need a file that lets the runtime know what version of Beamable it was built with... -->  
    <Message Text="Creating beamable version file..." Importance="high" />  
    <WriteLinesToFile File="$(OutDir)/.beamablesdkversion" Lines="$(BeamableVersion)" Overwrite="true" />  
</Target>  
  
<!-- When running in a container, before building, we need to prepare a few files -->  
<Target Name="docker-setup-beamable" BeforeTargets="Build" DependsOnTargets="RunResolvePackageDependencies" Condition="$(DOTNET_RUNNING_IN_CONTAINER)==true">  
  
    <PropertyGroup>        <BeamableVersion>@(BeamablePackage->'%(Version)')</BeamableVersion>  
    </PropertyGroup>    <Message Text="Generating files..." Importance="high" />  
    <WriteLinesToFile File="$(PublishDir)/.beamablesdkversion" Lines="$(BeamableVersion)" Overwrite="true" />  
    <WriteLinesToFile File="$(PublishDir)/.env" Lines="BEAMABLE_SDK_VERSION_EXECUTION=$(BeamableVersion)" Overwrite="true" />  
</Target>

The following property group section can be dramatically simplified. The only required properties from the following snippet are,

  1. GenerateClientCode, and
  2. TargetFramework
<!--  Settings for Beamable Build  -->  
<PropertyGroup>  
    <!-- The tool path for the beamCLI. "dotnet beam" will refer to the local project tool, and "beam" would install to a globally installed tool -->  
    <BeamableTool>beam</BeamableTool>  
  
    <!-- When "true", this will open a website to the local swagger page for the running service -->  
    <OpenLocalSwaggerOnRun>false</OpenLocalSwaggerOnRun>  
  
    <!-- When "true", this will auto-generate client code to any linked unity projects -->  
    <GenerateClientCode>true</GenerateClientCode>  
</PropertyGroup>  
  
<PropertyGroup Condition="$(DOTNET_RUNNING_IN_CONTAINER)!=true">  
    <DefineConstants>$(DefineConstants);BEAMABLE_GENERATE_ENV</DefineConstants>  
</PropertyGroup>  
  
<!-- Standard dotnet settings-->  
<PropertyGroup>  
    <OutputType>Exe</OutputType>  
  
    <!-- As of Beamable 1.0, net6.0 is required. -->  
    <TargetFramework>net6.0</TargetFramework>  
    <!-- Advanced C# Features are disabled by default. The Unity SDK does not support these features.   
         If you enable them, it will be harder to copy/paste code between the service and Unity. -->  
    <ImplicitUsings>disable</ImplicitUsings>  
    <Nullable>disable</Nullable>  
    <DockerDefaultTargetOS>Linux</DockerDefaultTargetOS>  
  
    <!-- Warning 1591 is about missing XML comments on methods. Beamable suggests disabling this warning.   
         https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/compiler-messages/cs1591 -->  
    <NoWarn>1591</NoWarn>  
  
    <!-- The autogenerated OpenAPI page will use the generated serviceDocs.xml file to handle   
         API descriptions. The OpenAPI page will break if there is no `serviceDocs.xml` file. -->  
    <GenerateDocumentationFile>true</GenerateDocumentationFile>  
</PropertyGroup>

However, there is one new property that is REQUIRED. You must add the following property,

<BeamProjectType>service</BeamProjectType>

After all the edits, you should have a csproj file that looks similar to the following. This is the csproj file that is generated for a new service using CLI 2.0.1.

<Project Sdk="Microsoft.NET.Sdk">  
    <PropertyGroup Label="Beamable Settings">  
        <!-- All Microservices must have the value, "service" -->  
        <BeamProjectType>service</BeamProjectType>  
  
        <!-- When "true", this will auto-generate client code to any linked unity projects -->  
        <GenerateClientCode>true</GenerateClientCode>  
    </PropertyGroup>  
    <PropertyGroup Label="Dotnet Settings">  
        <!-- net8.0 is the LTS version until 2026. To update your net version, update the <TargetFramework> when Beamable announces support. -->  
        <TargetFramework>net6.0</TargetFramework>  
    </PropertyGroup>  
    <ItemGroup Label="Nuget References">  
        <PackageReference Include="Beamable.Microservice.Runtime" Version="2.0.1" />  
    </ItemGroup>  
</Project>
Common Libraries

Similar to services, the csproj file for common libraries has been simplified between major versions 1 and 2.

You should remove this target,

<!-- Move the built dll to the linked projects -->  
<Target Name="share-code" AfterTargets="Build" Condition="$(CopyToLinkedProjects)==true AND $(DOTNET_RUNNING_IN_CONTAINER)!=true">  
    <Message Text="Generating code for other projects" Importance="high" />  
    <Exec Command="$(BeamableTool) project share-code $(OutDir)/$(AssemblyName).dll --dep-prefix-blacklist Newtonsoft,Unity.Beamable,UnityEngine,Unity.Addressables,System" />  
</Target>

And from the following properties the only two that you need are,

  1. CopyToLinkedProjects, and
  2. TargetFramework
  
<PropertyGroup>  
    <!-- Unity 2021 can handle netstandard2.1 libraries -->  
    <TargetFramework>netstandard2.1</TargetFramework>  
    <GenerateDocumentationFile>true</GenerateDocumentationFile>  
</PropertyGroup>  
  
<!--  Settings for Beamable Build  -->  
<PropertyGroup>  
    <!-- The tool path for the beamCLI. "dotnet beam" will refer to the local project tool, and "beam" would install to a globally installed tool -->  
    <BeamableTool>beam</BeamableTool>  
  
    <!-- When "true", this will copy the built project and associated dependencies to linked Unity projects -->  
    <CopyToLinkedProjects>true</CopyToLinkedProjects>  
</PropertyGroup>  
  
<!-- Make sure that the built dlls and their dependencies are in the output directory -->  
<PropertyGroup>  
    <ProduceReferenceAssemblyInOutDir>true</ProduceReferenceAssemblyInOutDir>  
    <CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies>  
    <PublishDocumentationFile>true</PublishDocumentationFile>  
</PropertyGroup>

When you are done with these edits, your csproj file should appear similar to the following snippet. Here is the csproj file for a common library created with CLI 2.0.1.

<Project Sdk="Microsoft.NET.Sdk">

    <PropertyGroup>
        <!-- Unity 2021 can handle netstandard2.1 libraries -->
        <TargetFramework>netstandard2.1</TargetFramework>
    </PropertyGroup>

    <!--  Settings for Beamable Build  -->
    <PropertyGroup>
        <!-- When "true", this will copy the built project and associated dependencies to linked Unity projects -->
        <CopyToLinkedProjects>true</CopyToLinkedProjects>
    </PropertyGroup>

    <ItemGroup>
      <PackageReference Include="Beamable.Common" Version="2.0.1" />
    </ItemGroup>
    
</Project>

Dockerfiles

Any service you created in 1.19.22 will have a Dockerfile. These files need some manual edits to make them compatible with 2.0.1.

Select all the lines between the first FROM command, and the RUN dotnet publish command, and replace them with the following.

# <BEAM-CLI-COPY-ENV> this line signals the start of environment variables copies into the built container. Do not remove it. This will be overwritten every time a variable changes in the execution of the CLI.  
  
# </BEAM-CLI-COPY-ENV> this line signals the end of environment variables copies into the built container. Do not remove it.  
  
# <BEAM-CLI-COPY-SRC> this line signals the start of Beamable Project Src copies into the built container. Do not remove it. The content between here and the closing tag will change anytime the Beam CLI modifies dependencies.  
  
# </BEAM-CLI-COPY-SRC> this line signals the end of Beamable Project Src copies. Do not remove it.  
  
# build the dotnet program  
WORKDIR /

Next, select the lines starting with (and including) RUN dotnet publish until the line (but not including) ENTRYPOINT , and replace them with the following,

RUN dotnet publish ${BEAM_CSPROJ_PATH} -c release -o /beamApp  
  
# use the dotnet runtime as the final stage  
FROM mcr.microsoft.com/dotnet/runtime:6.0-alpine  
WORKDIR /beamApp  
  
# expose the health port  
EXPOSE 6565   
# copy the built program  
COPY --from=build-env /beamApp .

Finally, on the last line (the ENTRYPOINT), replace the /subapp with /beamApp

Here is a Dockerfile that was adapted from 2.0.1. There are two important things to note,

  1. this file is for a service called Example3, which justifies the ENTRYPOINT, and
  2. when you run beam services run, the CLI will inject content into the file between on the BEAM-CLI- tags. After the command runs, you should see ENV, RUN, and COPY statements between the beamable tags. This is how the ${BEAM_CSPROJ_PATH} reference will be resolved.
# use the dotnet sdk as a build stage  
FROM mcr.microsoft.com/dotnet/sdk:6.0-alpine as build-env  
  
# <BEAM-CLI-COPY-ENV> this line signals the start of environment variables copies into the built container. Do not remove it. This will be overwritten every time a variable changes in the execution of the CLI.  
  
# </BEAM-CLI-COPY-ENV> this line signals the end of environment variables copies into the built container. Do not remove it.  
  
# <BEAM-CLI-COPY-SRC> this line signals the start of Beamable Project Src copies into the built container. Do not remove it. The content between here and the closing tag will change anytime the Beam CLI modifies dependencies.  
  
# </BEAM-CLI-COPY-SRC> this line signals the end of Beamable Project Src copies. Do not remove it.  
  
# build the dotnet program  
WORKDIR /  
  
RUN dotnet publish ${BEAM_CSPROJ_PATH} -c release -o /beamApp  
  
# use the dotnet runtime as the final stage  
FROM mcr.microsoft.com/dotnet/runtime:6.0-alpine  
WORKDIR /beamApp  
  
# expose the health port  
EXPOSE 6565   
# copy the built program  
COPY --from=build-env /beamApp .  
  
# when starting the container, run dotnet with the built dll  
ENTRYPOINT ["dotnet", "/beamApp/Example3.dll"]  

Microservice .config folders

Finally, the .config folder under each Microservice folder should be deleted. This file is cruft, and is no longer needed.

Also, remember that if your Microservice is referencing a Storage object, you must have Docker running; otherwise the Microservice will not start correctly.