Introduction
This article demonstrates how to create console applications on Mac OS X (10.12.3), Ubuntu 14.04 and Windows 10 using .NET Core. This article gives the details of OS versions, Tools set and a demo. We will create a multiple project solution using Visual Studio Code, which contains two Console Applications and 4 Library Projects. We will learn how to add Project Reference and Package Reference. We will also see how to configure and execute two console applications within the same solution. Please refer to (Part 3) my previous article which creates multiple project solutions with single console application (.NET Core Console Applications On Mac OS X, Ubuntu 14.04 And Windows 10 - Part Three). Also please refer to Part 1 & 2 of the article to give the basics. The main use case is that development teams are working on the same code base with the same tool set, and the key is different Operating System.
The code tested on below Operating System Versions,
- Mac OS X (10.12.3)
- Ubuntu 14.04
- Windows 10
Tools Set
- .NET Core 1.0.4
- .NET Command Line Interface (cli) Tools
- Visual Studio Code (1.12.2)
- Git
Source Code Link.
Demo 1 - Multiple Projects [2 Console Application and 4 Library projects] using terminal, cli, and Visual Studio Code
- Introduction to the solution
This solution will contain 6 projects.
- DataCore.csproj
This project contains the data model. This will be used to hold the metadata of the libraries (StringLibrary, ArrayLibrary).
- CoreLibrary.csproj
This project contains two interfaces. IRunner and IProcessor.
- ArrayLibrary.csproj
This project contains an ArrayDemo.cs class, which will accept an array and prints the array in reverse.
- StringLibrary.csproj
This project contains two classes. PalindromicString.cs displays whether a given string is Palindrome or not. ToggleString.cs toggles each alphabet.
- LogicPrograms.csproj
This is the console application project. It consumes both StringLibrary.csproj and ArrayLibrary.csproj. It will read the metadata from appsettings.json and executes the methods from each class using Metadata. It uses reflection.
- StringPrograms.csproj
This is the console application project. It consumes only StringLibrary.csproj. It will read the metadata from appsettings.json and executes the methods from each class using Metadata. It uses reflection.
Please refer to the image to get a better picture.
Mac OS X (10.12.3)
Get the latest version of code from GitHub.
git pull
Create a Folder called MultiLibMultiApps. Copy and Paste the five (DataCore, CoreLibrary, ArrayLibrary, StringLibrary, LogicPrograms) Projects which we created in MultiLibraryApp. Please refer Part 3 of the article.
Open MultiLibMultiApps folder in Visual Studio. Your solution should look similar to the image below.
Select Program.cs inside LogicPrograms folder. Visual Studio Code will display a dialog box for creation .vscode folder with launch.json and tasks.json. Please select “Yes”.
Also change the console type inside launch.json to “integratedTerminal”, so that we will be able to input the data to the program.
-
- "console": "integratedTerminal",
- "stopAtEntry": false,
- "internalConsoleOptions": "openOnSessionStart"
- },
Execute the solution, it should work and invoke the methods from 3 three classes.
Within the integrated terminal execute the below mentioned commands to create new console application within existing solution.
mkdir StringPrograms
cd StringPrograms
dotnet new console
dotnet restore
Now we have two console applications. We have to instruct Visual Studio Code to execute which particular console application. For this we have to modify launch.json and tasks.json.
Launch.json
We should add Launch configuration for each application that should be executed. In the below code we have two configurations, one for LogicPrograms and another for StringPrograms. The “program” element should point to the binary of that console application which will be launched. In our case LogicPrograms.dll and StringPrograms.dll.
- {
- "name": ".NET Core Launch (LogicPrograms)",
- "type": "coreclr",
- "request": "launch",
- "preLaunchTask": "build",
-
- "program": "${workspaceRoot}/LogicPrograms/bin/Debug/netcoreapp1.1/LogicPrograms.dll",
- "args": [],
- "cwd": "${workspaceRoot}/LogicPrograms",
-
- "console": "integratedTerminal",
- "stopAtEntry": false,
- "internalConsoleOptions": "openOnSessionStart"
- },
- {
- "name": ".NET Core Launch (StringPrograms)",
- "type": "coreclr",
- "request": "launch",
- "preLaunchTask": "build",
-
- "program": "${workspaceRoot}/StringPrograms/bin/Debug/netcoreapp1.1/StringPrograms.dll",
- "args": [],
- "cwd": "${workspaceRoot}/StringPrograms",
-
- "console": "integratedTerminal",
- "stopAtEntry": false,
- "internalConsoleOptions": "openOnSessionStart"
- }
Once we navigate to debug mode, we will be able to see all the configuration items which was defined in the launch.json. In our case we have added two Launch configuration items for both console applications.
Note
- ${workspaceRoot} the path of the folder opened in VS Code
- ${fileDirname} the current opened file's dirname
- ${cwd} the task runner's current working directory on startup
Tasks.json
Build command runs from ${workspaceRoot}. But in our case we have two separate executable under different folders. Also the “args” element will specify which project to compile.
- "tasks": [
- {
- "taskName": "build",
- "args": [
- "${workspaceRoot}/LogicPrograms/LogicPrograms.csproj"
- ],
- "isBuildCommand": true,
- "problemMatcher": "$msCompile"
- }
We need to make two changes. We need to remove the arguments/path of the project from “args” element. Also need to include “options” element with “cmd” element.
- {
- "version": "0.1.0",
- "command": "dotnet",
- "isShellCommand": true,
- "args": [],
- "options": {
- "cwd": "${fileDirname}"
- },
- "tasks": [
- {
- "taskName": "build",
- "args": [ ],
- "isBuildCommand": true,
- "problemMatcher": "$msCompile"
- }
- ]
- }
Select the Program.cs within StringPrograms project. In the Debug Mode select “.NET Core Launch (StringPrograms)” and execute the program, you should see “Hello World” as output.
Select the Program.cs within LogicPrograms project. In the Debug Mode select “.NET Core Launch (LogicPrograms)” and execute the program, it should invoke the methods from ArrayLibrary and StringLibrary classes.
Till now we have created 2nd console application. Configured to execute each console applications.
Windows 10
Now will be update StringProgram to consume only StringLibrary project. Get the latest code from GitHub.
git pull
Update the dependencies of all the projects.
dotne restore
StringPrograms.csproj
Create a new file called appsettings.json and paste the below mentioned code.
- [
- {
- "AssemblyName": "StringLibrary",
- "MethodName": "Process"
- }
- ]
Add two Project Reference (Library within solution) and one Package Reference (Base Class Library/Nuget) to StringPrograms.csproj.
- <Project Sdk="Microsoft.NET.Sdk">
- <PropertyGroup>
- <OutputType>Exe</OutputType>
- <TargetFramework>netcoreapp1.1</TargetFramework>
- </PropertyGroup>
- <ItemGroup>
- <PackageReference Include="System.Runtime.Serialization.Json">
- <Version>*</Version>
- </PackageReference>
- <ProjectReference Include="../DataCore/DataCore.csproj" />
- <ProjectReference Include="../StringLibrary/StringLibrary.csproj" />
- </ItemGroup>
- </Project>
As we have updated StringPrograms.csproj, we need to restore the dependencies by executing dotnet restore.
dotnet restore
Open Program.cs and replace with the below code.
- using static System.Console;
- using System.Reflection;
- using System.Collections.Generic;
- using System.IO;
- using System.Runtime.Serialization.Json;
- using DataCore;
-
- namespace StringPrograms
- {
- class Program
- {
- static void Main(string[] args)
- {
- var metadata = GetMetadata("appsettings.json");
-
- foreach (var current in metadata)
- {
- ExecuteMethods(current);
- }
-
- WriteLine("\n\nPress any key ...");
- ReadKey();
- }
-
- #region Private Methods.
- private static void ExecuteMethods(Metadata currentAssembly)
- {
- var programsAssembly = Assembly.Load(new AssemblyName(currentAssembly.AssemblyName));
- foreach (var currentClass in programsAssembly.GetTypes())
- {
- var currentMethod = currentClass.GetMethod(currentAssembly.MethodName);
- WriteLine($"{currentClass.Name} ....");
- currentMethod.Invoke(System.Activator.CreateInstance(currentClass), null);
- }
- }
-
- static List<Metadata> GetMetadata(string metadataFilePath)
- {
- var metadataFileStream = File.Open(metadataFilePath, FileMode.Open);
- var serializer = new DataContractJsonSerializer(typeof(List<Metadata>));
- return (List<Metadata>)serializer.ReadObject(metadataFileStream);
- }
- #endregion
- }
- }
Select the Program.cs within StringPrograms project. In the Debug Mode select “.NET Core Launch (StringPrograms)” and execute the program, you should see method from both the classes in StringLibrary are called successfully.
We can use the integration Git within Visual Studio Code to push the code to GitHub.
Ubuntu 14.04
Get the latest code from GitHub. Open Visual Studio Code with MultiLibMultiApps opened.
We need to restore the dependencies by executing dotnet restore for all the 6 projects.
dotnet restore
Select the Program.cs within LogicPrograms project and add a comment and check in the code into GitHub.
- namespace StringPrograms
- {
-
-
-
-
-
- class Program
Select the Program.cs within StringPrograms project. In the Debug Mode select “.NET Core Launch (StringPrograms)” and execute the program, you should see method from both the classes are called successfully. You should be able to input the data using integrated Terminal.
Summary
In this article, I discussed how we can create console applications using .net code and C#. We also saw how to create these in Mac OS X (10.12.3), Ubuntu 14.04 and Windows 10. We also saw the same code works on Mac OS X (10.12.3), Ubuntu 14.04 and Windows 10.