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.
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
Within the integrated terminal execute the below mentioned commands to create 5 projects.
DataCore.csproj
- DataCore.csproj:
- mkdir DataCore
- cd DataCore
- dotnet new classlib
- dotnet restore
- cd ..
Image for reference: for Project creation steps for single project.
Repeat the similar steps for the reset of the 4 projects.
CoreLibrary.csproj
- mkdir CoreLibrary
- cd CoreLibrary
- dotnet new classlib
- dotnet restore
- cd ..
ArrayLibrary.csproj
- mkdir ArrayLibrary
- cd ArrayLibrary
- dotnet new classlib
- dotnet restore
- cd ..
StringLibrary.csproj
- mkdir StringLibrary
- cd StringLibrary
- dotnet new classlib
- dotnet restore
- cd ..
LogicPrograms.csproj
- mkdir LogicPrograms
- cd LogicPrograms
- dotnet new console
- dotnet restore
- cd ..
The solution should like the image below.
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.
DataCore.csproj
Rename Class1.cs to Metadata.cs. Replace the code with below mentioned code.
- namespace DataCore
- {
- public class Metadata
- {
- public string AssemblyName;
- public string MethodName;
- }
- }
CoreLibrary.csproj
Rename Class1.cs to IRunner.cs. Replace the code with below mentioned code.
- namespace CoreLibrary
- {
- public interface IRunner
- {
- #region Methods
- void Run();
- #endregion
- }
- }
Create a new file named IProcessor.cs and replace with the below mentioned code.
- namespace CoreLibrary
- {
- public interface IProcessor
- {
- #region Methods
- void Process();
- #endregion
- }
- }
ArrayLibrary.csproj
Inside ArrayLibrary.csproj, add project reference of CoreLibrary.csproj.
- <Project Sdk="Microsoft.NET.Sdk">
- <PropertyGroup>
- <TargetFramework>netstandard1.4</TargetFramework>
- </PropertyGroup>
- <ItemGroup>
- <ProjectReference Include="../CoreLibrary/CoreLibrary.csproj" />
- </ItemGroup>
- </Project>
Rename Class1.cs to ArrayDemo.cs. Replace the code with below mentioned code.
- using System.Linq;
- using CoreLibrary;
- using static System.Console;
-
- namespace ArrayLibrary
- {
- public class ArrayDemo : IRunner
- {
- public void Run()
- {
- WriteLine("Sample Input {5 4 3 2 1}");
- var arrayValues = ReadLine().Trim().Split(' ').Select(int.Parse).ToArray();
- WriteLine(string.Join(" ", arrayValues.Reverse()));
- }
- }
- }
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
LogicPrograms.csproj
Create a new file called appsettings.json and paste the below mentioned code.
- [
- {
- "AssemblyName": "ArrayLibrary",
- "MethodName": "Run"
- }
- ]
Add two Project Reference (Library within solution) and one Package Reference (Base Class Library/Nuget) to LogicPrograms.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="../ArrayLibrary/ArrayLibrary.csproj" />
- </ItemGroup>
- </Project>
As we have updated LogicPrograms.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 LogicPrograms
- {
-
-
-
- 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
- }
- }
Switch to Debug mode and execute the program. You should see similar output. But … wait!!! We are unable to give input???
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").
- {
- "name": ".NET Core Launch (console)",
- "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"
- },
Now execute the program, we should be able to input through integrated terminal within Visual Studio Code.
-
- "console": "externalTerminal",
Now execute the program, we should be able to input through external terminal.
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.
- <Project Sdk="Microsoft.NET.Sdk">
- <PropertyGroup>
- <TargetFramework>netstandard1.4</TargetFramework>
- </PropertyGroup>
- <ItemGroup>
- <ProjectReference Include="../CoreLibrary/CoreLibrary.csproj" />
- </ItemGroup>
- </Project>
We need to restore the dependencies by executing dotnet restore.
dotnet restore
Rename class1.cs to PalindromicString.cs. Replace the code with below mentioned code.
- using static System.Console;
- using CoreLibrary;
-
- namespace StringLibrary
- {
- public class PalindromicString : IProcessor
- {
- #region Methods
- public void Process()
- {
- var jCtr = 0;
- var output = "YES";
- var data = ReadLine().Trim();
-
- for (var iCtr = data.Length - 1; iCtr >= 0; iCtr--, jCtr++)
- {
-
- if (char.ToLowerInvariant(data[iCtr]).Equals(char.ToLowerInvariant(data[jCtr])))
- {
- continue;
- }
- output = "NO";
- break;
- }
- WriteLine(output);
- }
- #endregion
- }
- }
Create a new file named ToggleString.cs. Replace the code with below mentioned code.
- using static System.Console;
- using CoreLibrary;
-
- namespace StringLibrary
- {
- public class ToggleString : IProcessor
- {
- #region Methods
- public void Process()
- {
- WriteLine("Sample Input {abcdE}");
- var data = ReadLine();
- var output = 0;
- foreach (var currentChar in data)
- {
- if ((currentChar >= 65 && currentChar <= 90))
- {
- output = currentChar + 32;
- }
- else if ((currentChar >= 97 && currentChar <= 122))
- {
- output = currentChar - 32;
- }
- else
- {
- output = currentChar;
- }
- Write($"{(char)output}");
- }
- }
- #endregion
- }
- }
LogicPrograms.csproj
Update LogicPrograms.csproj with StringLibrary’s project reference.
- <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="../ArrayLibrary/ArrayLibrary.csproj" />
- <ProjectReference Include="../StringLibrary/StringLibrary.csproj" />
- </ItemGroup>
- </Project>
Update appsettings.json with StringLibrary’s metadata and paste the below mentioned code.
- [
- {
- "AssemblyName": "ArrayLibrary",
- "MethodName": "Run"
- },
- {
- "AssemblyName": "StringLibrary",
- "MethodName": "Process"
- }
- ]
We need to restore the dependencies by executing dotnet restore.
dotnet restore
Execute the program. It will traverse through all the libraries mentioned in metadata json, executes the Run/Process methods.
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.
We need to restore the dependencies by executing dotnet restore for all the 5 projects.
dotnet restore
Select the Program.cs within LogicPrograms project and add a comment “/// Updated in Ubuntu 14.04.”. Check in the code into GitHub.
- namespace LogicPrograms
- {
-
-
-
-
- class Program
Execute the Program. You should be able to input the data using integrated Terminal.
Mac OS X (10.12.3)
Get the latest code from GitHub. Open Visual Studio Code with MultiLibraryApp opened.
We need to restore the dependencies by executing dotnet restore for all the 5 projects.
dotnet restore
Select the Program.cs within LogicPrograms project and add a comment “/// Updated in Mac OS X too.”. Check in the code into GitHub.
- namespace LogicPrograms
- {
-
-
-
-
-
- class Program
Execute the Program. 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.