Helpful tips on the topic;
Visual Studio licensing and pricing
There are two models. Subscription based and Volume licensing program; The subscription-based pricing is on Microsoft web site;
https://visualstudio.microsoft.com/vs/pricing/?tab=business
Professional = $45 per month
Enterprise = $250 per month
Microsoft has partners that might be able to help you in lowering subscription pricing by applying discounts that are not available to general public. In one instance I have been offered Enterprise edition @2,500/year for 5 developers.
Estimated pricing for volume licensing program (5 developers);
This program has one-time payment. This is a perpetual license and if software assurance is involved, you are eligible to get newer version. MSDN subscriptions are usually valid for two years. MSDN renewal is a recurring expense and cost about 20-30% of software cost.
Here is the breakdown;
Professional
The minimum limit here is 5 because there is no MSDN subscription.
Microsoft Visual Studio 2019 Professional – License – 1 User – Microsoft Open License – Single Language – PC
$496.57 x 5 = $2,482.85
Professional with MSDN
Microsoft Visual Studio Professional Edition with MSDN – License & Software Assurance – 1 User – Microsoft Qualified – Microsoft Open Business – All Languages – PC
$1,080.87 x 5 = $5,404.35
Enterprise with MSDN
Microsoft Visual Studio Enterprise With MSDN – License & Software Assurance – 1 User – Volume, Microsoft Qualified – All Languages – PC
$8,638.64 x 5 = 43,193.20
If budget is a constraint and wanted software assurance then I will suggest to go for Professional with MSDN. You can pick whatever suits you.
There are 3rd party vendors offer lower rates but not sure how that will work out. Here is one.
Resource
https://visualstudio.microsoft.com/vs/pricing-details/
https://docs.microsoft.com/en-us/visualstudio/subscriptions/volume-license
Install and configure Git for windows
Download Git from here;
https://git-scm.com/download/win
This is required if you want to use git from command prompt. A reboot is required after installation.
Visual Studio 2019 Settings
This is required to integrate with Azure Devops.
Tools -> Get Tools and Features -> Individual components
Search “git”. Select “Git for Windows” from menu;

Visual studio will take some time to reconfigure.
Visual Studio 2017 Settings
Open Visual Studio, Check the Git for Windows in the Tools – Get Tools and Features…), go to “Individual Item” tab, check “Git for Windows”, and click “Modify”. Then it will ask you to update Visual Studio to the latest version, for example 15.9.36.

Click ok to install and close.
Reflection – What are the benefits
Generally, when people talk about reflection, the main concern is the performance. Because it runs on runtime, so theoretically, it is a little bit slower than the normal application. But it is flexible for many scenarios, especially if you develop the framework. If it is acceptable to spend a few seconds (or only hundreds of milliseconds) to load assemblies, then feel free to use it.
Let’s walk through an example; We are going to use an interface called “ISpeaker”.
internal interface ISpeaker
{
string SayHello();
}
Create three implementation classes:
English Speakers
internal class EnglishSpeaker : ISpeaker
{
public string Name => this.GetType().ToString();
public string SayHello()
{
return "Hello!";
}
}
Urdu Speakers
internal class UrduSpeaker : ISpeaker
{
public string Name => this.GetType().ToString();
public string SayHello()
{
return "as-salaam-alaikum";
}
}
Chinese Speakers
internal class ChineseSpeaker : ISpeaker
{
public string Name => this.GetType().ToString();
public string SayHello()
{
return "Nihao";
}
}
Now we can use reflection to find all the implementations of ISpeaker
interface and call their methods or properties.
internal class ReflectionHelper
{
public static List<Type> GetAvailableSpeakers()
{
// You can also use AppDomain.CurrentDomain.GetAssemblies() to load all assemblies in the current domain.
// Get the specified assembly.
var assembly =
Assembly.LoadFrom(Path.Combine(Directory.GetCurrentDirectory(), "ReflectionDemo.dll"));
// Find all the types in the assembly.
var types = assembly.GetTypes();
// Apply the filter to find the implementations of ISayHello interface.
var result = types.Where(x => x.IsClass && typeof(ISpeaker).IsAssignableFrom(x)).ToList();
// Or you can use types.Where(x => x.IsClass && x.GetInterfaces().Contains(typeof(ISpeaker))).ToList();
return result;
}
}
In this class, we load the specified dll file that contains types we need. Then we can apply the LINQ query to find all the implementations of ISpeaker
interface using Reflection.
Test the program output. we can output the name and call SayHello
method of each speaker:
using ReflectionDemo;
using System.Reflection;
Console.WriteLine("Hello, World!");
Console.WriteLine("Here is the Reflection sample:");
// Find all the speakers in the current domain
var availableSpeakers = ReflectionHelper.GetAvailableSpeakers();
foreach (var availableSpeaker in availableSpeakers)
{
// Create the instance of the type
var speaker = Activator.CreateInstance(availableSpeaker);
// Get the property info of the given property name
PropertyInfo namePropertyInfo = availableSpeaker.GetProperty("Name");
// Then you can get the value of the property
var name = namePropertyInfo?.GetValue(speaker)?.ToString();
Console.WriteLine($"I am {name}");
// Invoke the method of the instance
Console.WriteLine(availableSpeaker.InvokeMember("SayHello", BindingFlags.InvokeMethod, null, speaker, null));
}
Console.WriteLine();
Console.ReadKey();
Run the program, you will see the below output:

If we need to add other speakers in other languages, just add the implementation classes in the same project. .NET reflection can automatically find out all the required classes and call the methods correctly.
It is extremely useful when we create the plugin-type applications. First we make the interfaces and call the methods from the client by reflection. Then we can create plugins following the interface for the client, which can be loaded as the *.dll files dynamically and executed.
Another scenario is for the framework development. As a framework developer, you will not be able to know what implementations the users will create, so you can only use reflection to create these instances. One example is in some MVVM frameworks, if you create the classes following the conventions, eg. xxxViewModel, the framework can find all the ViewModels and load them automatically using reflection.
The main namespaces we need to use for reflection are System.Reflection and System.Type. You may also need to know the below terms:
- Assembly
- Module
- ConstructorInfo
- MethodInfo
- FieldInfo
- EventInfo
- PropertyInfo
- ParameterInfo
- CustomAttributeData
Resources
Dynamically Loading and Using Types
https://docs.microsoft.com/en-us/dotnet/core/tutorials/creating-app-with-plugin-support
Rest API HATEOAS (Hypermedia as the Engine of Application State)
REST architecture allows us to generate hypermedia links in our responses dynamically and thus make navigation much easier. To put this into perspective, think about a website that uses hyperlinks to help you navigate to different parts of it. You can achieve the same effect with HATEOAS in your REST API.
The advantage of the above approach is that hypermedia links returned from the server drive the application’s state and not the other way around.
A REST client hits an initial API URI and uses the server-provided links to access the resources it needs and discover available actions dynamically.
The client need not have prior knowledge of the service or the different steps involved in a workflow. Additionally, the clients no longer have to hardcode the URI structures for various resources. HATEOAS allows the server to make URI changes as the API evolves without breaking the clients.
Let’s say we need to define an API that guides a client through a signature process. In this process after getting a Resource, the resource will include a Link indicating the following elements that are necessary. The plan is to add a signature link in this example:
{
"documentID": 10,
"documentType": "Contract",
"content": "Lorem ipsum dolor sit amet, consectetur adipiscing elit."
"links": [
{
"href": "10/signatures",
"rel": "approval",
"type" : "POST"
}
]
}
The recommendation is to add a link to xsd/schema document which will define the structure of model attributes. e.g.
"links": [
{
"href": "10/signatures",
"rel": "approval",
"type" : "POST",
"schema" : "/schemas/signature.xsd"
}
]
Now the client can read the XSD document to find out about the model. This approach wouldn’t process the request but return the model XSD/schema document to the client. In this way, when client want to POST on 10/signatures
, it may get the request schema by GET 10/signatures.xsd
.
Resources
https://thereisnorightway.blogspot.com/2012/05/api-example-using-rest.html
https://medium.com/@andreasreiser94/why-hateoas-is-useless-and-what-that-means-for-rest-a65194471bc8
https://netflix.github.io/genie/docs/3.0.0/rest/#_introduction