.NET Core Console Applications On Mac OS X, Ubuntu 14.04 And Windows 10 - Part Three

.Net Core Console Applications On Mac OS X, Ubuntu 14.04 And Windows 10.

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, toolset, and a demo. We will create a multiple project solution using Visual Studio Code, which contains one Console Applications and 4 Library Projects. We will learn how to add Project Reference and Package Reference. We will also see how to accept input with integrated terminal and external terminal. Please refer to my previous article for basics on developing console applications using .Net core.

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 [1 Console Application and 4 Library projects] using terminal, cli, and Visual Studio Code

Introduction to the solution: This solution will contain 5 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 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.

.Net Core

Windows 10

Within integrated terminal of Visual Studio Code, create a folder called MultiLibraryApp and navigate to it. Open the same folder in Visual Studio Code using File Menu.

mkdir MultiLibraryApp

cd MultiLibraryApp

.Net Core

Within the integrated terminal execute the below mentioned commands to create 5 projects.

DataCore.csproj 

  1. DataCore.csproj:   
  2. mkdir DataCore  
  3. cd DataCore  
  4. dotnet new classlib  
  5. dotnet restore  
  6. cd ..   

Image for reference: for Project creation steps for single project.

.Net Core

Repeat the similar steps for the reset of the 4 projects.

CoreLibrary.csproj 

  1. mkdir CoreLibrary  
  2. cd CoreLibrary  
  3. dotnet new classlib  
  4. dotnet restore  
  5. cd ..   

ArrayLibrary.csproj 

  1. mkdir ArrayLibrary  
  2. cd ArrayLibrary  
  3. dotnet new classlib  
  4. dotnet restore  
  5. cd ..   

StringLibrary.csproj 

  1. mkdir StringLibrary  
  2. cd StringLibrary  
  3. dotnet new classlib  
  4. dotnet restore  
  5. cd ..   

LogicPrograms.csproj 

  1. mkdir LogicPrograms  
  2. cd LogicPrograms  
  3. dotnet new console  
  4. dotnet restore  
  5. cd ..   

The solution should like the image below.

.Net Core

Select the Program.cs within LogicPrograms project. Visual Studio Code will display a dialog box for creation of .vscode folder with launch.json and tasks.json. Please click on Yes.

.Net Core

DataCore.csproj

Rename Class1.cs to Metadata.cs. Replace the code with below mentioned code. 

  1. namespace DataCore  
  2. {  
  3.     public class Metadata  
  4.     {  
  5.         public string AssemblyName;  
  6.         public string MethodName;  
  7.     }  
  8. }   

CoreLibrary.csproj

Rename Class1.cs to IRunner.cs. Replace the code with below mentioned code. 

  1. namespace CoreLibrary  
  2. {  
  3.     public interface IRunner  
  4.     {  
  5.         #region Methods  
  6.         void Run();  
  7.         #endregion  
  8.     }  
  9. }   

Create a new file named IProcessor.cs and replace with the below mentioned code. 

  1. namespace CoreLibrary  
  2. {  
  3.     public interface IProcessor  
  4.     {  
  5.         #region Methods  
  6.         void Process();  
  7.         #endregion  
  8.     }  
  9. }   

ArrayLibrary.csproj

Inside ArrayLibrary.csproj, add project reference of CoreLibrary.csproj. 

  1. <Project Sdk="Microsoft.NET.Sdk">  
  2.   <PropertyGroup>  
  3.     <TargetFramework>netstandard1.4</TargetFramework>  
  4.   </PropertyGroup>  
  5.   <ItemGroup>  
  6.     <ProjectReference Include="../CoreLibrary/CoreLibrary.csproj" />  
  7.   </ItemGroup>  
  8. </Project>   

Rename Class1.cs to ArrayDemo.cs. Replace the code with below mentioned code. 

  1. using System.Linq;  
  2. using CoreLibrary;  
  3. using static System.Console;  
  4.   
  5. namespace ArrayLibrary  
  6. {  
  7.     public class ArrayDemo : IRunner  
  8.     {  
  9.         public void Run()  
  10.         {  
  11.             WriteLine("Sample Input {5 4 3 2 1}");  
  12.             var arrayValues = ReadLine().Trim().Split(' ').Select(int.Parse).ToArray();  
  13.             WriteLine(string.Join(" ", arrayValues.Reverse()));  
  14.         }  
  15.     }  
  16. }   

Within the integrated terminal perform dotnet restore for ArrayLibrary.csproj. Whenever we change any configuration (.csproj), we have to execute the dotnet restore to get the updated dependencies.

dotnet restore

.Net Core

LogicPrograms.csproj

Create a new file called appsettings.json and paste the below mentioned code. 

  1. [  
  2.     {  
  3.         "AssemblyName""ArrayLibrary",  
  4.         "MethodName""Run"  
  5.     }  
  6. ]   

Add two Project Reference (Library within solution) and one Package Reference (Base Class Library/Nuget) to LogicPrograms.csproj. 

  1. <Project Sdk="Microsoft.NET.Sdk">  
  2.   <PropertyGroup>  
  3.     <OutputType>Exe</OutputType>  
  4.     <TargetFramework>netcoreapp1.1</TargetFramework>  
  5.   </PropertyGroup>  
  6.   <ItemGroup>  
  7.     <PackageReference Include="System.Runtime.Serialization.Json">  
  8.       <Version>*</Version>  
  9.     </PackageReference>  
  10.     <ProjectReference Include="../DataCore/DataCore.csproj" />  
  11.     <ProjectReference Include="../ArrayLibrary/ArrayLibrary.csproj" />  
  12.   </ItemGroup>  
  13. </Project>   

As we have updated LogicPrograms.csproj, we need to restore the dependencies by executing dotnet restore.

dotnet restore

.Net Core

Open Program.cs and replace with the below code. 

  1. using static System.Console;  
  2. using System.Reflection;  
  3. using System.Collections.Generic;  
  4. using System.IO;  
  5. using System.Runtime.Serialization.Json;  
  6. using DataCore;  
  7.   
  8. namespace LogicPrograms  
  9. {  
  10.     /// <summary>  
  11.     /// Project created in Windows 10.   
  12.     /// </summary>  
  13.     class Program  
  14.     {  
  15.         static void Main(string[] args)  
  16.         {  
  17.             var metadata = GetMetadata("appsettings.json");  
  18.   
  19.             foreach (var current in metadata)  
  20.             {  
  21.                 ExecuteMethods(current);  
  22.             }  
  23.   
  24.             WriteLine("\n\nPress any key ...");  
  25.             ReadKey();  
  26.         }  
  27.  
  28.         #region Private Methods.  
  29.         private static void ExecuteMethods(Metadata currentAssembly)  
  30.         {  
  31.             var programsAssembly = Assembly.Load(new AssemblyName(currentAssembly.AssemblyName));  
  32.             foreach (var currentClass in programsAssembly.GetTypes())  
  33.             {  
  34.                 var currentMethod = currentClass.GetMethod(currentAssembly.MethodName);  
  35.                 WriteLine($"{currentClass.Name} ....");  
  36.                 currentMethod.Invoke(System.Activator.CreateInstance(currentClass), null);  
  37.             }  
  38.         }  
  39.   
  40.         static List<Metadata> GetMetadata(string metadataFilePath)  
  41.         {  
  42.             var metadataFileStream = File.Open(metadataFilePath, FileMode.Open);  
  43.             var serializer = new DataContractJsonSerializer(typeof(List<Metadata>));  
  44.             return (List<Metadata>)serializer.ReadObject(metadataFileStream);  
  45.         }  
  46.         #endregion  
  47.     }  
  48. }   

Switch to Debug mode and execute the program. You should see similar output. But … wait!!! We are unable to give input???

.Net Core

Inside .vscode folder, Open launch.json. “console” ("console": "internalConsole") element will by default be used only to output the content. To accept the input we need to change the value to ("console": "integratedTerminal" OR "console": "externalTerminal").

  1. {  
  2.     "name"".NET Core Launch (console)",  
  3.     "type""coreclr",  
  4.     "request""launch",  
  5.     "preLaunchTask""build",  
  6.     // If you have changed target frameworks, make sure to update the program path.  
  7.     "program""${workspaceRoot}/LogicPrograms/bin/Debug/netcoreapp1.1/LogicPrograms.dll",  
  8.     "args": [],  
  9.     "cwd""${workspaceRoot}/LogicPrograms",  
  10.     // For more information about the 'console' field, see https://github.com/OmniSharp/omnisharp-vscode/blob/master/debugger-launchjson.md#console-terminal-window  
  11.     "console""integratedTerminal",  
  12.     "stopAtEntry"false,  
  13.     "internalConsoleOptions""openOnSessionStart"  
  14. },   

Now execute the program, we should be able to input through integrated terminal within Visual Studio Code.

.Net Core

  1. // For more information about the 'console' field, see https://github.com/OmniSharp/omnisharp-vscode/blob/master/debugger-launchjson.md#console-terminal-window  
  2. "console""externalTerminal",   

Now execute the program, we should be able to input through external terminal.

.Net Core

Check in the code into GitHub. So far we have seen that CoreLibrary.csproj has been consumed by ArrayLibrary.csproj. LogicPrograms.csproj consumes both DataCore.csproj and ArrayLibrary.csproj. Program.cs reads the metadata from appsettings.json file and executes the methods from class inside ArrayLibrary.csproj; using reflection. Now let’s build the String Library.

StringLibrary.csproj

Update StringLibrary.csproj to include the Project Reference. 

  1. <Project Sdk="Microsoft.NET.Sdk">  
  2.   <PropertyGroup>  
  3.     <TargetFramework>netstandard1.4</TargetFramework>  
  4.   </PropertyGroup>  
  5.   <ItemGroup>  
  6.     <ProjectReference Include="../CoreLibrary/CoreLibrary.csproj" />  
  7.   </ItemGroup>  
  8. </Project>   

We need to restore the dependencies by executing dotnet restore.

dotnet restore

.Net Core

Rename class1.cs to PalindromicString.cs. Replace the code with below mentioned code. 

  1. using static System.Console;  
  2. using CoreLibrary;  
  3.   
  4. namespace StringLibrary  
  5. {  
  6.     public class PalindromicString : IProcessor  
  7.     {  
  8.         #region Methods  
  9.         public void Process()  
  10.         {  
  11.             var jCtr = 0;  
  12.             var output = "YES";  
  13.             var data = ReadLine().Trim();  
  14.   
  15.             for (var iCtr = data.Length - 1; iCtr >= 0; iCtr--, jCtr++)  
  16.             {  
  17.                   
  18.                 if (char.ToLowerInvariant(data[iCtr]).Equals(char.ToLowerInvariant(data[jCtr])))  
  19.                 {  
  20.                     continue;  
  21.                 }  
  22.                 output = "NO";  
  23.                 break;  
  24.             }  
  25.             WriteLine(output);  
  26.         }  
  27.         #endregion  
  28.     }  
  29. }   

Create a new file named ToggleString.cs. Replace the code with below mentioned code. 

  1. using static System.Console;  
  2. using CoreLibrary;  
  3.   
  4. namespace StringLibrary  
  5. {  
  6.     public class ToggleString : IProcessor  
  7.     {  
  8.         #region Methods  
  9.         public void Process()  
  10.         {  
  11.             WriteLine("Sample Input {abcdE}");  
  12.             var data = ReadLine();  
  13.             var output = 0;  
  14.             foreach (var currentChar in data)  
  15.             {  
  16.                 if ((currentChar >= 65 && currentChar <= 90))  
  17.                 {  
  18.                     output = currentChar + 32;  
  19.                 }  
  20.                 else if ((currentChar >= 97 && currentChar <= 122))  
  21.                 {  
  22.                     output = currentChar - 32;  
  23.                 }  
  24.                 else  
  25.                 {  
  26.                     output = currentChar;  
  27.                 }  
  28.                 Write($"{(char)output}");  
  29.             }  
  30.         }  
  31.         #endregion  
  32.     }  
  33. }   

LogicPrograms.csproj

Update LogicPrograms.csproj with StringLibrary’s project reference. 

  1. <Project Sdk="Microsoft.NET.Sdk">  
  2.   <PropertyGroup>  
  3.     <OutputType>Exe</OutputType>  
  4.     <TargetFramework>netcoreapp1.1</TargetFramework>  
  5.   </PropertyGroup>  
  6.   <ItemGroup>  
  7.     <PackageReference Include="System.Runtime.Serialization.Json">  
  8.       <Version>*</Version>  
  9.     </PackageReference>  
  10.     <ProjectReference Include="../DataCore/DataCore.csproj" />  
  11.     <ProjectReference Include="../ArrayLibrary/ArrayLibrary.csproj" />  
  12.     <ProjectReference Include="../StringLibrary/StringLibrary.csproj" />  
  13.   </ItemGroup>  
  14. </Project>   

Update appsettings.json with StringLibrary’s metadata and paste the below mentioned code. 

  1. [  
  2.     {  
  3.         "AssemblyName""ArrayLibrary",  
  4.         "MethodName""Run"  
  5.     },  
  6.     {  
  7.         "AssemblyName""StringLibrary",  
  8.         "MethodName""Process"  
  9.     }  
  10. ]   

We need to restore the dependencies by executing dotnet restore.

dotnet restore

.Net Core

Execute the program. It will traverse through all the libraries mentioned in metadata json, executes the Run/Process methods.

.Net Core

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 MultiLibraryApp opened.

.Net Core
.Net Core

We need to restore the dependencies by executing dotnet restore for all the 5 projects.

dotnet restore

.Net Core

Select the Program.cs within LogicPrograms project and add a comment “/// Updated in Ubuntu 14.04.”. Check in the code into GitHub. 

  1. namespace LogicPrograms  
  2. {  
  3.     /// <summary>  
  4.     /// Project created in Windows 10.   
  5.     /// Updated in Ubuntu 14.04.  
  6.     /// </summary>  
  7.     class Program   


.Net Core

Execute the Program. You should be able to input the data using integrated Terminal.

.Net Core

Mac OS X (10.12.3)

Get the latest code from GitHub. Open Visual Studio Code with MultiLibraryApp opened.

.Net Core

We need to restore the dependencies by executing dotnet restore for all the 5 projects.

dotnet restore

.Net Core

Select the Program.cs within LogicPrograms project and add a comment “/// Updated in Mac OS X too.”. Check in the code into GitHub. 

  1. namespace LogicPrograms  
  2. {  
  3.     /// <summary>  
  4.     /// Project created in Windows 10.   
  5.     /// Updated in Ubuntu 14.04.  
  6.     /// Updated in Mac OS X too.  
  7.     /// </summary>  
  8.     class Program   

Execute the Program. You should be able to input the data using integrated Terminal.

.Net Core

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.