This article is about C# coding within text editor or Visual Studio Code, referencing one .NET project from another and compilation using CSC command line tool.
Introduction
Nowadays, writing .NET C# applications becomes a routine process, which is a significantly different activity from the origins of the programming - being a personal hobby. For a technical specialist with more than 12 years of professional experience developing C# .NET applications, engaging all the power of modern code writing enhancements, e.g., ReSharper autocomplete, Debugger, Intellisense, etc. - coding becomes a pointless routine. At that time, sometimes a wish comes to write a piece of code without all of those things that make software development an automation industry instead of being a personal hobby. Logging messages within DOS console, keeping in mind types, local variables, function definitions, testing every function by lunching an app - that's what this article is about.
Background
Writing code using modern tools for software development make it feel like code writes by itself. At some point, it might be challenging to do simple coding using primitive, primordial techniques.
Using the Code
Inarguably, there are valuable advantages and benefits of using modern tools for software development. Altogether: autocomplete, debugger and intellisense make the code writing process pretty simple and straight forward. However, this article is not about the pros and cons of these modern tools. The article briefly describes how to write a C# library and console application using primitive DOS commands, reference projects, build it using CSC compilation tool and Visual Studio Code (same as any other text editor).
Why Visual Studio Code? Because it shows inbuilt project explorer with project structure that simplifies access to project files, it also has simple Terminal and Console sections within the code editor. One can write the code and execute commands within the same application window. This is very convenient in combination with large displays. It doesn't have usual for C# developers enhancements, e.g., spell check, intellisense, inbuilt attachable debugger, autocomplete, etc.
For making a simplest .NET C# application everything that is needed - a text file with compilable C# code and CSC tool for compiling code into binary. CSC is the compiler that processes text C# code and generates binary code (executable or library). MSBuild is a utility, which allows making readable configuration for the CSC compiler.
For simplicity, I'm going to create a class library and console application which utilizes (references) that library. .NET Framework 3.5 is the runtime.
Launch Visual Studio Code, open the Terminal by pressing Ctrl+`.
mkdir PizzaLib
cd PizzaLib
mkdir .vscode
cd .vscode
type nul > tasks.json
cd ..
type nul > PizzaShop.cs
type nul > DeliveryService.cs
mkdir bin
Configuring Project Build Process to Deliver the Compiled DLL File
Open that new project in Visual Studio Code (using shortcut Ctrl+K Ctrl+O).
Then double click the /.vscode/tasks.json file and configure the build process:
{
"version": "2.0.0",
"tasks": [
{
"label": "pizzalibbuild",
"command": "C:\\Windows\\Microsoft.NET\\Framework\\v3.5\\CSC.exe",
"type":"shell",
"args": [
"/t:library",
"/out:bin/PizzaLib.dll",
"*.cs"
],
"group": {
"kind": "build",
"isDefault": true
}
}
]
}
The tasks.json file is a configuration file, which is used by Visual Studio Code to perform translation, compilation, build, assembly actions prior to delivering final DLL file or executable. Each Task node within that file defines a single command, e.g., shell (which can be bash script, CMD, PowerShell) or process to execute a list of arguments to supply when executing the command. Configuration option: group -> kind -> "build" defines this task as default for building the project (when Ctrl+Shift+B shortcut is pressed).
Library Code
Sample 'PizzaLib.dll' library is responsible for cooking pizza and delivering it to the customer. Two classes should be defined: PizzaShop.cs and DeliveryService.cs - one is for ordering and cooking the pizza, another one is for delivering pizza to the customer.
PizzaShop.cs
using System;
namespace PizzaLib
{
public class PizzaShop
{
public void OrderPizza()
{
Console.WriteLine("Pizza Mozzarella with cheese. Your order is being processed.");
}
public void CookPizza()
{
Console.WriteLine("Cooking delicious pizza...");
}
}
}
DeliveryService.cs
using System;
namespace PizzaLib
{
public class DeliveryService
{
public void Deliver()
{
Console.WriteLine("Delivering to customer.");
}
}
}
When code is written, it is time to configure build tasks. Press Ctrl+Shift+B to build the library. The job is done, the library is compiled and can be referenced by another application (console application in this particular case).
Console Application to use PizzaLib for Ordering and Delivering Pizza
Open another instance of the Visual Studio Code, make a similar structure for the console application.
mkdir PizzaConsoleTest
cd PizzaConsoleTest
mkdir .vscode
cd .vscode
type nul > tasks.json
type nul > launch.json
cd ..
type nul > PizzaConsoleTest.cs
mkdir bin
cd ..
Open that directory in the Visual Studio Code using shortcut Ctrl+K Ctrl+O.
Configure the build (tasks.json) and launch process (launch.json) by following the guide below:
tasks.json
{
"version": "2.0.0",
"tasks": [
{
"label": "pizzaconsoletestbuild",
"command": "C:\\Windows\\Microsoft.NET\\Framework\\v3.5\\CSC.exe",
"type": "shell",
"args": [
"/r:\"../PizzaLib/bin/PizzaLib.dll\",\"../PizzaLib/bin/PizzaLib.dll\"",
"/out:bin/PizzaConsoleTest.exe",
"*.cs"
],
"group": {
"kind": "build",
"isDefault": true
}
}
]
}
This file is almost identical to the tasks.json configured for the PizzaLib
project, however, notice how /r
CSC compiler option defines referenced 'PizzaLib.dll' library: /r:"../PizzaLib/bin/PizzaLib.dll","../PizzaLib/bin/PizzaLib.dll"
launch.json
{
"version": "0.2.0",
"configurations": [
{
"name": "PizzaConsoleTestLauncher",
"type": "clr",
"request": "launch",
"preLaunchTask": "pizzaconsoletestbuild",
"program": "${workspaceFolder}/bin/PizzaConsoleTest.exe",
"args":[],
"console": "internalConsole",
"stopAtEntry": false,
"internalConsoleOptions": "openOnSessionStart"
}
]
}
The launch.json file defines Visual Studio Code configuration options for debugging or executing the compiled project. This file is valid for projects, that have executable output. It simply specifies which actions should be taken prior to executing the final file and its optional arguments. In this case, configuration defines build task, named "pizzaconsoletestbuild
" to execute prior to launching the final, compiled executable.
Okay, let's use PizzaShop
library to cook and deliver delicious pizza. Adding the code to the PizzaConsoleTest.cs application file:
using System;
using PizzaLib;
namespace PizzaConsoleTest
{
public class Program
{
public static void Main(string[] args)
{
Console.WriteLine("Ordering Pizza with PizzaLib");
PizzaShop pizzaShop = new PizzaShop();
pizzaShop.OrderPizza();
pizzaShop.CookPizza();
DeliveryService deliveryService = new DeliveryService();
deliveryService.Deliver();
}
}
}
If you review the tasks.json file carefully, the CSC compiler is configured to use referenced library PizzaLib.dll, while the remaining thing is to copy that library into console application 'bin' folder, in order to make it available at the time of the console application execution:
copy /Y "..\..\PizzaLib\bin\PizzaLib.dll" "bin\PizzaLib.dll"
If everything is configured correctly, simply pressing Ctrl+F5 would execute the console application with the following result:
-------------------------------------------------------------------
You may only use the Microsoft .NET Core Debugger (vsdbg) with
Visual Studio Code, Visual Studio or Visual Studio for Mac software
to help you develop and test your applications.
-------------------------------------------------------------------
Ordering Pizza with PizzaLib
Pizza Mozzarella with cheese. Your order is being processed.
Cooking delicious pizza...
Delivering to customer.
The program '[7152] PizzaConsoleTest.exe' has exited with code 0 (0x0).
Points of Interest
Command line interface and simple text editor would make it extremely hard to develop a multi-modular, distributed web application due to configurational difficulties and code complexity. This easy practice is just a point of interest. Complex development environment, which has modern coding enhancements gives much more abilities and flexibility for building bulky systems.
History
- 3rd March, 2020: Initial version