Thursday, December 13, 2018

.NET Core 2.2: Executing Code Prior to Main Method

Last week .NET Core 2.2 was released with some nice features and in this post, let’s see one of them which is executing code before the Main method.

As we all know the Main method is the entry point of a program. But .NET Core 2.2 is introducing this feature called Host startup hook and it provides a mechanism to execute code before executing the Main method.

I have created two class library projects named StartupHook1 and StartupHook2 and both of them are targeting .NET Core 2.2. Inside both of the projects, I am adding a class named StartupHook.
using System.Diagnostics;
using System.Reflection;
 
internal class StartupHook
{
    public static void Initialize()
    {
        Debug.WriteLine($"{Assembly.GetExecutingAssembly().GetName().Name} is called.");
    }
}

Note: The type must be named StartupHook without any namespace and it should be internal. And inside the class, we should have a static method named Initialize. For the sake of the post, I am just logging a message inside the method.

When I build the projects, I will have two dlls, StartupHook1 and StartupHook2.

Now take an existing .NET Core 2.2 application. For the demo, let’s just create an ASP.NET Core 2.2 Web Application. And to link the web application and the two class libraries (which are startup hooks), we need to add an environment variable named DOTNET_STARTUP_HOOKS to the web application as follows. We can easily do that by going to web application project properties and adding an environment variable.

image
ENVIRONMENT VARIABLE
It’s basically something like below.
DOTNET_STARTUP_HOOKS=SomePath\StartupHook1.dll;SomePath\StartupHook2.dll
Now I will just modify the web applications Main method to add some logging.
public static void Main(string[] args)
{
    Debug.WriteLine("Main is called.");
 
    CreateWebHostBuilder(args).Build().Run();
}

Now if I run the ASP.NET Core web application, I am seeing the below.

image
Debug Output
You can see that the Initialize methods in both StartupHook1 and StartupHook2 has been called before the actual entry point. And the execution order is the order we have defined the hooks in the environment variable.

Isn’t it nice.

For more information,
   Host startup hook

Happy Coding.

Regards,
Jaliya

Saturday, December 8, 2018

C# 8.0: Nullable Reference Types

Past week has been amazing, there were a lot of new announcements at Microsoft Connect(); 2018. Two of them are the first previews of both Visual Studio 2019 and .NET Core 3.0 (Visual Studio 16.0.0 Preview 1.0 and .NET Core 3.0.0 Preview 1).

And with these, we get the opportunity to try out some of the features which will be coming in C# 8.0. In this post, let’s go through Nullable Reference Types which is one of them.

Without explaining the feature, let’s consider the following code.
class Program
{
    static void Main(string[] args)
    {
        Employee employee = null;
        Console.WriteLine(employee.Name);
    }
}
 
class Employee
{
    public string Name { get; set; }
}
The code is pretty obvious, you can see that when the employee is null, trying to access its property Name will throw a NullReferenceException.

Now closely look at the following two pictures. First one is when we are on C# 7.3 (Visual Studio 15.9.3) and the second one is when we are on C# 8.0 (Visual Studio 16.0.0 Preview 1.0). If you are wondering how to select language version in Visual Studio, check out this post
image
C# 7.3 (Visual Studio 15.9.3)
image
C# 8.0 (Visual Studio 16.0.0 Preview 1.0)
I am sure you can spot the difference. Visual Studio is not issueing any warnings in the first picture, but in the second, Visual Studio is issuing a couple of warnings.

This is because C# 8.0 is introducing nullable reference types and non-nullable reference types. So starting with C# 8.0, all the reference type variables are not nullable and if the compiler sees a code trying to dereference a non-nullable reference type, it will issue a warning. But as of now, you are opted-out for this feature by default. You can opt-in to this feature (which is known as nullable contexts) using the following two approaches.
  • Project Wide:
This is by adding the following line to the .csproj file right after the LanguageVersion.
<NullableReferenceTypes>true</NullableReferenceTypes>
  • Using a newly introduced pragma, #nullable.
#nullable enable
#nullable disable
I am using project-wide setting for the post here.

Now if we have a look at the warnings Visual Studio complains about, it has three warnings.

CS8600: Converting null literal or possible null value to non-nullable type.

This is because our the variable employee of type Employee is no longer nullable. If we expect the variable to be nullable, we can change the variable initialization as follows (just as we will do for values types).
Employee? employee = null;
And prior to C# 8.0 this wasn’t possible.

CS8602: Possible dereference of a null reference.

Since our employee variable can be null, we need to update the code to add null conditional operator which got introduced with C# 6.
Console.WriteLine(employee?.Name);
CS8618: Non-nullable property 'Name' is uninitialized.

This is a nice one. Name property of Employee is a type of string and string is a reference type. Now in our sample, employee is null meaning that a value for Name is not set. To fix this we can update the code as follows.
public string? Name { get; set; }
And again this wasn’t possible prior to C# 8.0.

null-forgiving operator (!.)

This is another feature which is part of nullable reference types. Consider the below code.
class Program
{
    static void Main(string[] args)
    {
        Employee? employee = null;
        // some code
        Console.WriteLine(employee.Name);
    }
}
 
class Employee
{
    public string? Name { get; set; }
}
This will again issue us “CS8602: Possible dereference of a null reference”. If we know employee is not going to be null because of some code, we can override the warning by updating the code as below.
Console.WriteLine(employee!.Name);
I am sure nullable reference types will tremendously help us in writing quality code.

Happy Coding.

Regards,
Jaliya

Tuesday, November 27, 2018

Visual C# and ASP.NET Technical Guru - October 2018

Another month as a judge in Microsoft TechNet Guru Awards. And this it’s under both Visual C# and ASP.NET category. The TechNet Guru Awards celebrate the technical articles on Microsoft TechNet.

Post in WikiNinjas Official Blog,
image
]Visual C# Technical Guru - October 2018
Well, this time under Visual C# there were not much articles as it was used to be.
image
ASP.NET Technical Guru - October 2018
Happy Coding.

Regards,
Jaliya

Sunday, November 25, 2018

Visual Studio 2017 Version 15.9 and .NET Core Tooling

A couple of days back Visual Studio 2017 Version 15.9 was released and it is the final minor update to Visual Studio 2017. As of now, 2 service updates have been already released and currently, it’s on 15.9.2.
image
Visual Studio About
One of the major features released with Visual Studio 15.9 is an update to how Visual Studio Tools for .NET Core determines the version to .NET Core SDK to use with.

Prior versions were using whatever the latest .NET Core SDK installed in your machine, meaning that even if you have installed a preview version of .NET Core SDK, a stable version of Visual Studio was using that preview version.

So starting from Visual Studio 15.9, it will be defaulted to use the latest stable .NET Core SDK installed in your machine. But you can always choose to opt-in to use the preview versions of .NET Core SDK in Visual Studio by going to Tools->Options->Projects and Solutions->.NET Core and selecting Use previews of the .NET Core SDK.
image
.NET Core Options
I also have the latest preview version of Visual Studio 2017 installed which is Version 15.9.0 Preview 6.0 as of now.
image
Visual Studio About
But in the preview versions, I can’t opt out from using the preview versions of .NET Core SDK.
image
.NET Core Options
The option is disabled and the reason is, for Visual Studio to work properly, it needs the preview versions.

Hope this helps.

Happy Coding.

Regards,
Jaliya

Tuesday, November 20, 2018

Wrote a post on Wiki Life at Official Blog of TechNet Wiki

Wrote a post in Wiki Ninjas - Official Blog of TechNet Wiki. The title of the post is TNWiki Article Spotlight - Blazor: CRUD Using MongoDB.
image
TNWiki Article Spotlight - Blazor: CRUD Using MongoDB

Happy Coding.

Regards,
Jaliya

Sunday, November 18, 2018

ASP.NET Core: Important Things to Consider When Configuring Cookie Authentication

In this post, let’s go through two of the important things to consider when configuring Cookie Authentication in an ASP.NET Core Application.
services
     .AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
     .AddCookie(CookieAuthenticationDefaults.AuthenticationScheme, x =>
     {
          // other configuration
          x.Cookie.SecurePolicy = CookieSecurePolicy.SameAsRequest;
          x.Cookie.SameSite = SameSiteMode.None;
     })
Cookie.SecurePolicy and Cookie.SameSite plays a major role in Cookie authentication.

Cookie.SecurePolicy

This is an enum of type CookieSecurePolicy.
  • SameAsRequest: This is the default. If the server has provided the cookie to the client over HTTP, then all subsequent HTTP and HTTPS requests can return the cookie to the server. If it was over HTTPS, only HTTPS requests can take the cookie back.
  • Always: When this is set, your cookie will only sent in HTTPS requests.
  • None: When this is set, even the cookie is sent to the client in HTTPS, all your HTTP and HTTPS requests can take the cookie back to the server.

Cookie.SameSite

This is an enum of type SameSiteMode. This specifies how the cookie will be sent in cross-site requests.
  • None: No mode is specified.
  • Lax: The cookie will be sent with "same-site" requests, and with "cross-site" top-level navigation.
  • Strict: When the value is Strict, or if the value is invalid, the cookie will only be sent along with "same-site" requests.
An important thing to note is, the Cookie Policy Middleware setting for MinimumSameSitePolicy will override your setting of Cookie.SameSite as the matrix below. (Reference: Cookie Policy Middleware)
image
Matrix
Hope this helps.

Happy Coding.

Regards,
Jaliya

Thursday, November 1, 2018

Visual C# Technical Guru - September 2018

Another month as a judge in Microsoft TechNet Guru Awards under Visual C# category. The TechNet Guru Awards celebrate the technical articles on Microsoft TechNet.

Post in WikiNinjas Official Blog,
https://blogs.technet.microsoft.com/wikininjas/2018/11/01/technet-guru-awards-september-2018/

image
Visual C# Technical Guru - September 2018
Happy Coding.

Regards,
Jaliya

Sunday, October 28, 2018

ASP.NET Core In-Memory Caching

In this post let’s go through how server-side caching can be used in an ASP.NET Core Application, specially in-memory caching.

Caching can be used to improve the performance of an application. For an example, say that you have an API endpoint and there, you are returning some data after querying a database, and you are sure the related data is not going to get refreshed for a certain period of time, maybe daily. In that case, there is no point of querying the database each time your endpoint is being called within that day. So in the initial call, you can query the database, cache them and for the next subsequent calls, you can return the data from the cache. Then after that certain period of time expires, elicit the data in the cache and start from the beginning.

The in-memory caching uses web servers memory to store the cache. So now an interesting question comes, what if the application is running on multiple servers then how can the cache is shared. In such scenario, either we will need to enforce sticky sessions (specific session and all its subsequent sessions being directed to the same server) or distributed caching (doesn't use local memory and uses some other providers to maintain the cache Microsoft SQL Server, Redis etc.). In this post, we are assuming sticky sessions are in place.

ASP.NET Core provides 2 options.
public class MemoryCache : IDisposable, Microsoft.Extensions.Caching.Memory.IMemoryCache
This one is the preferred in the world of ASP.NET Core, as you can see it implements IMemoryCache and nicely integrated to ASP.NET Core DI.
public class MemoryCache : System.Runtime.Caching.ObjectCache, IDisposable
This one comes for .NET Framework, but still as long you target .NET Standard 2.0 or above, you can use this.

Now let’s see how we can use in-memory caching using Microsoft.Extensions.Caching.Memory.MemoryCache.

I have created an ASP.NET Core Web API application using the default template.

First, you need to register IMemoryCache. We don’t explicitly need to register, there is an extension method already available.
public void ConfigureServices(IServiceCollection services)
{
    services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
 
    services.AddMemoryCache();
}
Next, in the controllers’ constructor, I can inject IMemoryCache.
public IMemoryCache _memoryCache { get; }
 
public ValuesController(IMemoryCache memoryCache)
{
    _memoryCache = memoryCache;
}
And use as follows.
[HttpGet]
public ActionResult<IEnumerable<string>> Get()
{
    string key = "Somekey";
 
    if (!_memoryCache.TryGetValue(key, out DateTime cacheValue))
    {
        cacheValue = DateTime.Now;
 
        var cacheEntryOptions = new MemoryCacheEntryOptions()
            .SetSlidingExpiration(TimeSpan.FromSeconds(30));
 
        _memoryCache.Set(key, cacheValue, cacheEntryOptions);
    }
 
    return new string[] { $"Cached: { cacheValue.ToString()}", $"Actual: { DateTime.Now.ToString()}" };
}
The cache contains EntriesCollection which is maintained using keys. The logic is simple, we are adding items to EntriesCollection identified by a key, and when we add we can set a variety of options (MemoryCacheEntryOptions).

  • AbsoluteExpiration
Gets or sets an absolute expiration date for the cache entry.
  • AbsoluteExpirationRelativeToNow
Gets or sets an absolute expiration time, relative to now.
  • ExpirationTokens
Gets the IChangeToken instances which cause the cache entry to expire.
  • PostEvictionCallbacks
Gets or sets the callbacks will be fired after the cache entry is evicted from the cache.
  • Priority
Gets or sets the priority for keeping the cache entry in the cache during a memory pressure triggered cleanup. The default is Normal.
  • Size
Gets or sets the size of the cache entry value.
  • SlidingExpiration    
Gets or sets how long a cache entry can be inactive (e.g. not accessed) before it will be removed. This will not extend the entry lifetime beyond the absolute expiration (if set).

More reading,
Cache in-memory in ASP.NET Core

Hope this helps.

Happy Coding.

Regards,
Jaliya

Thursday, October 11, 2018

.NET Core on macOS: Code Coverage with Coverlet

I wanted to check the code coverage on a .NET Core project I am working on. But I am on macOS, and unfortunately, Visual Studio for Mac nor JetBrains Rider (on macOS) does not support code coverage as of today. JetBrains is going to port dotCover to be cross-platform so we will have Rider + dotCover in near future which is something to look forward to.

I found this brilliant tool coverlet developed by Toni Solarin-Sodara. Coverlet is a cross-platform code coverage library for .NET Core, with support for line, branch and method coverage. I just gave it a try now, it looks amazing and with very little steps, I can get the code coverage.

First I need to add the coverlet.msbuild nuget package to the unit test project.
# From the folder which contains UnitTests.csproj file
dotnet add package coverlet.msbuild

# If the folder contains multiple .csproj files, specify the targetted .csproj file
dotnet add <MyProject.UnitTests.csproj> package coverlet.msbuild
Then I can just run,
dotnet test <MyProject.UnitTests.csproj> /p:CollectCoverage=true
But for some reason, I was getting this error "...coverlet.msbuild.targets: error: Failed to resolve assembly:...". After a little bit of googling, found this issue where it says to run dotnet test command with /p:CopyLocalLockFileAssemblies=true flag.
dotnet test <MyProject.UnitTests.csproj> /p:CollectCoverage=true /p:CopyLocalLockFileAssemblies=true
And yes, that did it and I am presented with most awaited code coverage.

Code Coverage
There are a lot of options that you can configure with coverlet and you should definitely try it.

Hope this helps.

Happy Coding.

Regards,
Jaliya

Tuesday, October 2, 2018

ASP.NET Core: Setting Up HTTPS Local Development Certificate in macOS

In this post let’s see how we can configure local HTTPS certificate in macOS for an ASP.NET Core web application.

You can use dotnet-dev-cert which is a command line tool to generate certificates used in ASP.NET Core during local development. To install the tool, you can simply run the following command (note: the version can be different, it's the version as of today).
dotnet tool install --global dotnet-dev-certs --version 2.1.1 
Once installed, you can generate a certificate just by running the below command.
dotnet dev-certs https -ep localhost.pfx -p dev
image
dotnet dev-certs
You can run the command with --help flag to see more options about the tool.
dotnet dev-certs https --help

image
dotnet dev-certs https --help
Once the certificate is generated, you should be able to see the certificate in Keychain Access. You can easily open Keychain Access by using Spotlight or, navigating to Applications -> Utilities -> Keychain Access.

image
Keychain Access
Now you need to trust the certificate for SSL by double-clicking on the certificate, expanding Trust and selecting Always Trust in Secure Socket Layter (SSL) dropdown.
image
Keychain Access
Hope this helps.

Happy Coding.

Regards,
Jaliya

Sunday, September 30, 2018

Visual C# Technical Guru - August 2018

Another month as a judge in Microsoft TechNet Guru Awards under Visual C# category. The TechNet Guru Awards celebrate the technical articles on Microsoft TechNet.

Post in WikiNinjas Official Blog,
https://blogs.technet.microsoft.com/wikininjas/2018/09/30/technet-guru-competition-winners-august-2018/

Visual C# Technical Guru - August 2018
Happy Coding.

Regards,
Jaliya

Friday, September 21, 2018

JetBrains Rider, macOS and ASP.NET Core Web Application Permission Denied on localhost Port 80

At work, I am on macOS and using JetBrains Rider as the primary IDE. Switching to macOS and Rider was not at all easy, still struggling most of the time. Switching between Windows and macOS is more harder.

I wanted to run ASP.NET Core Web Application in localhost port 80, but it kept giving me permission denied error.
image
Permission Denied
Using the following command, I checked for any processes that use port 80, but unfortunately, there wasn’t any.
sudo lsof -i ':80'
Checked the firewall as well, and it was switched off. Then I realized, I was not running Rider as admin (sudo in macOS). Just googled how to start a program as sudo, and there wasn't any straightforward option just like Windows has as Run as administrator. But using the terminal, did able to get to Rider run as sudo.
sudo /Applications/Rider\ 2018.2.app/Contents/MacOS/rider 
image
run as sudo
But once it's started running as sudo, it is a fresh instance, meaning the IDE doesn't have any imported settings which is kind of bad. But it did solve the permission issue, web application successfully started running on port 80.

Thought this might help someone.

Happy Coding.

Regards,
Jaliya

Friday, September 7, 2018

Installing Redis on Windows

Recently I started working on a new project and we use Mac there. I wanted to have the development environment set up in my Windows machine and one of the requirements is I wanted to have a Redis instance there. Went to the Redis download page and surprisingly I couldn’t find any installer for Windows. I was looking for options.

I found this, MicrosoftArchive/redis on GitHub, a repository of Redis Windows port developed by Microsoft Open Tech. But unfortunately, that doesn’t seem to be maintained, the last Redis version available for download is Redis 3.2.1 while Redis 4.0.11 is the latest stable version.

I wasn’t quite convinced whether I should go with that, but then suddenly I remembered we have Docker. I should be able to get it up and running with just one command.
docker run --name redis -p 6379:6379 redis

image
docker run

The image got downloaded without any issue, but it didn’t start, failed with the error "Error response from daemon: driver failed programming external connectivity on endpoint redis".

Another bump, checked whether the image and container is present, it is.
image
Image
image
Container
Deleted the container named “redis”, restarted Docker and ran the command again. This time the image won't get downloaded since it's already present, will only create and start the container.

image
docker run
Redis container just started. Anyway, I wanted to make sure it's up and running.

image
docker ps
That is wonderful. It’s up. With very little steps, I have Redis running on Windows.

Happy Coding.

Regards,
Jaliya

Tuesday, September 4, 2018

Wrote a post on Wiki Life at Official Blog of TechNet Wiki

Wrote a post in Wiki Ninjas - Official Blog of TechNet Wiki. The title of the post is TNWiki Article Spotlight – ASP.NET Core Blazor Master/Detail CRUD with Filtering and Sorting using EF and Web API.
image
TNWiki Article Spotlight – ASP.NET Core Blazor Master/Detail CRUD with Filtering and Sorting using EF and Web API

Happy Coding.

Regards,
Jaliya

Sunday, September 2, 2018

ASP.NET Core: Transient/Scoped Instances Inside Middleware

I have faced this scenario where when requesting a Transient or Scoped instance from a constructor in a Custom Middleware it wasn’t giving me a Transient/Scoped instance, instead, it was giving me a singleton.

Let’s examine the problem in detail. Say I have the following interface, it’s implementation and a custom middleware.

IMyService.cs
public interface IMyService
{
    Guid GetGuid();
}
MyService.cs
public class MyService : IMyService
{
    private readonly Guid guid;
 
    public MyService()
    {
        guid = Guid.NewGuid();
    }
 
    public Guid GetGuid()
    {
        return guid;
    }
}
HelloWorldMiddleware.cs
public class HelloWorldMiddleware
{
    private readonly RequestDelegate _next;
    private readonly IMyService _myService;
 
    public HelloWorldMiddleware(RequestDelegate next,
        IMyService myService)
    {
        _next = next;
        _myService = myService;
    }
 
    public async Task Invoke(HttpContext httpContext)
    {
        await httpContext.Response.WriteAsync($"Hello World with {_myService.GetGuid()}");
    }
}
Now in my Startup.cs, I am registering IMyService and MyService as Transient and plugging in the HelloWorldMiddleware to the application pipeline.

Startup.cs
public class Startup
{
    public Startup(IConfiguration configuration)
    {
        Configuration = configuration;
    }
 
    public IConfiguration Configuration { get; }
 
    public void ConfigureServices(IServiceCollection services)
    {
        // Rest of the code ignored for brevity
 
        // Registering IMyService as Transient
        // Meaning a new instance is created each time it’s requested
        services.AddTransient&lt;IMyService, MyService>();
    }
 
    public void Configure(IApplicationBuilder app, IHostingEnvironment env)
    {
        // Rest of the code ignored for brevity
 
        // Setting the custom middleware to the pipeline
        app.Map("/api/helloworld", configuration =>
        {
            configuration.UseMiddleware&lt;HelloWorldMiddleware>();
        });
    }
}
So the idea is, each time I get navigated to “http://something/api/helloworld”, I get a response “Hello World” and that is with a new Guid. Because MyService constructor always creates a new Guid.

But no matter how many times I sent the request to “../api/helloworld”, I will get the same Guid. The reason is even though I have registered MyService as a Transient, the Middleware constructor will only get triggered once, and that is when the application is starting up. So here the constructor injection doesn’t work.

The workaround would be removing the constructor injection and request the service directly from context’s services.
public class HelloWorldMiddleware
{
    private readonly RequestDelegate _next;
 
    public HelloWorldMiddleware(RequestDelegate next)
    {
        _next = next;
    }
 
    public async Task Invoke(HttpContext httpContext)
    {
        IMyService _myService = httpContext.RequestServices.GetService&lt;IMyService>();
        await httpContext.Response.WriteAsync($"Hello World with {_myService.GetGuid()}");
    }
}
Now when I navigated to “../api/helloworld”, I will get an instance of MyService, if it was registered as Transient, I will get a Transient and if it was registered as Scoped or Singleton, I will get a Scoped or Singleton instance respectfully.

Hope this helps.

Happy Coding.

Regards,
Jaliya

Tuesday, August 28, 2018

Visual C# Technical Guru - July 2018

Another month as a judge in Microsoft TechNet Guru Awards under Visual C# category. The TechNet Guru Awards celebrate the technical articles on Microsoft TechNet.

image
Visual C# Technical Guru - July 2018
Happy Coding.

Regards,
Jaliya

Monday, August 27, 2018

What’s New with ASP.NET Core 2.2 Preview 1

ASP.NET Core 2.2 has beginning to shape up and is expected to be released before the end of this year.

If you want to try out some of the features, ASP.NET Core 2.2 Preview 1 is already released. As soon as you have the following running in your machine, you are all good to explore those.
image
ASP.NET Core 2.2
Following are the features of ASP.NET Core 2.2 Preview 1.
  • Template Updates: Use of Bootstrap 4, Angular 6 and clean up most of the boilerplate code)
image
Cleaned Up Templates
  • IIS In-process hosting
Right now, when an ASP.NET Core application is hosted in IIS, when a request is made, it’s being forward from w3wp.exe (known as IIS Worker Process) to dotnet.exe via Inter-Process Communication (IPC). This seems to have performance implications and ASP.NET Core team is trying to improve the performance by moving ASP.NET Core logic into IIS Worker Process itself.
  • Web API Conventions
  • HTTP/2
  • Endpoint Routing
  • Health Checks
  • SignalR Java Client

Check out
ASP.NET Core 2.2 Roadmap for more information.

That’s exciting, isn’t it.

Happy Coding.

Regards,
Jaliya

Tuesday, August 7, 2018

Docker: Windows Server 2016, ASP.NET Core 2.1 Runtime Image with Node

I wanted to have a docker image with Windows Server 2016 having ASP.NET Core 2.1 Runtime and Node installed, and didn’t find any official image that has them all (maybe there is and it’s just I couldn’t find).

But managed to get one created with some little extra steps.
# escape=`
# The escape directive sets the character used to escape and it's used both to escape characters in a line, 
# and to escape a newline. Below we have some commands spanning across multiple lines, so we need this.
# Note: It needs to be menioned before anything, yes, even before a comment.
 
FROM microsoft/dotnet:2.1.2-aspnetcore-runtime-nanoserver-sac2016
 
# The default shell on Windows is ["cmd", "/S", "/C"], Changing to PowerShell
SHELL["powershell", "-Command", "$ErrorActionPreference = 'Stop';"]
 
# Current Node LTS Version as of 07/08/2018
ENV NODE_VERSION 8.11.3
 
# Make sure to use the SHA of the specified Node version 
ENV NODE_VERSION_SHA 91b779def1b21dcd1def7fc9671a869a1e2f989952e76fdc08a5d73570075f31
 
# PowerShell commands to download and extract  
RUN Invoke-WebRequest https://nodejs.org/dist/v$Env:NODE_VERSION/node-v$Env:NODE_VERSION-win-x64.zip -OutFile node.zip; `
    if ((Get-FileHash node.zip -Algorithm sha256).Hash -ne $Env:NODE_VERSION_SHA) { `
        Write-Host 'CHECKSUM VERIFICATION FAILED!'; `
        exit 1; `
    }; `
    `
    Expand-Archive node.zip -DestinationPath node-temp; `
    Move-Item node-temp/node-v$Env:NODE_VERSION-win-x64 $Env:ProgramFiles/nodejs; `
    Remove-Item -Force node.zip; `
    Remove-Item -Force node-temp
 
# Setting Node to Path
RUN setx /M PATH $($Env:PATH + ';' + $Env:ProgramFiles + '/nodejs')
 
# Next steps is omitted

Hope this helps someone having the same requirement.

Happy Coding.

Regards,
Jaliya

Tuesday, July 31, 2018

Rest Parameters in TypeScript

In TypeScript, Rest Parameters are often used in functions to specify the parameters when the number of parameters is unknown.

Let’s go by a sample scenario. Imagine we need to have a method which will return us the full address (nicely separated by “,”) when different parts of the address are supplied. Some addresses have Address Line 1, Address Line 2 etc., and for some, there is no Address Line 2, likewise.

In this case, there is no fixed number of parameters. To cater such a requirement, we can have the following function with Rest Parameters.
function buildAddress(...addressLines) {
    return addressLines.join(", ");
};
Here the Rest Parameter is the addressLines, we are using JavaScript split operator (ellipsis) to specify that.

With TypeScript it’s always better to be explicit. You can specify the type of the Rest Parameters as well. And note, it should always be an array type as behind the scene it really is an array.
function buildAddress(...addressLines: string[]) {
    return addressLines.join(", ");
};
We can call the function like below.
console.log(buildAddress("111-2222", "Bing Street", "Springfield Gardens", "NY", "33333"));
// 111-2222, Bing Street, Springfield Gardens, NY, 33333

console.log(buildAddress("111-2222", "Springfield Gardens", "NY", "33333"));
// 111-2222, Springfield Gardens, NY, 33333
And you can even not pass anything at all.
console.log(buildAddress());
Isn’t it nice!

Happy Coding.

Regards,
Jaliya

Sunday, July 29, 2018

Visual C# Technical Guru - June 2018

Another month as a judge in Microsoft TechNet Guru Awards under Visual C# category. The TechNet Guru Awards celebrate the technical articles on Microsoft TechNet.

image
Visual C# Technical Guru - June 2018
Happy Coding.

Regards,
Jaliya

Sunday, July 1, 2018

Received Microsoft MVP Award in Visual Studio and Development Technologies

I am humbled, pleased and honored to receive the precious Microsoft Most Valuable Professional (MVP) Award for the fifth consecutive year. In the last couple of years received the award on 1st of January, but this time it's on 1st of July due to changes in Microsoft MVP Program. The expertise category which I received the award for is same as the last year, that is Visual Studio and Development Technologies. In the first two years, I have been awarded MVP for Visual C# and then .NET.

As always looking forward to another great year on top of Microsoft Development Stack.
MVPLogo_thumb[2]
Microsoft Most Valuable Professional (MVP)
Thank you Microsoft for your appreciation and Thank you Wellington PereraFiqri IsmailChaminda Chandrasekara and everyone for your continuous support and guidance.

Happy Coding.

Regards,
Jaliya

Friday, June 29, 2018

Visual C# Technical Guru - May 2018

Another month as a judge in Microsoft TechNet Guru Awards under Visual C# category. The TechNet Guru Awards celebrate the technical articles on Microsoft TechNet.

image
Visual C# Technical Guru - May 2018
Happy Coding.

Regards,
Jaliya

Wednesday, June 20, 2018

ASP.NET Core: FromServices Attribute

In this post let’s have a look at what FromServices attribute in ASP.NET Core brings in to the table.

Imagine I have the following interface and its implementation.
public interface IMyService
{
    string SayHello(string name);
}
 
public class MyService : IMyService
{
    public string SayHello(string name)
    {
        return $"Hello {name}";
    }
}
And I have IMyService registered with ASP.NET Core Services.
services.AddTransient<IMyService, MyService>();
Now imagine, I want to use IMyService.SayHello() method and in one of my controllers, but it’s going to be used in one single action.

Usually what we would be doing is, use constructor injection.
[Route("api/[controller]")]
[ApiController]
public class ValuesController : ControllerBase
{
    private readonly IMyService myService;
 
    public ValuesController(IMyService myService)
    {
        this.myService = myService;
    }
 
    [HttpGet("{name}")]
    public ActionResult<string> Get(string name)
    {
        return myService.SayHello(name);
    }
}
This looks fine, but if myService is going to be used only in Get(string name) action, having a separator field for IMyService and complicating constructor is really unnecessary.

In these type of situations, FromServices attribute is really handy.
[Route("api/[controller]")]
[ApiController]
public class ValuesController : ControllerBase
{
    [HttpGet("{name}")]
    public ActionResult<string> Get([FromServices] IMyService myService, string name)
    {
        return myService.SayHello(name);
    }
}
So when we decorate the parameter with FromServices attribute, the framework will look up the services container and inject the matching implementation. No need to do constructor injection at all. After all parameter injection is one of the ways we can do DI.

Hope this helps.

Happy Coding.

Regards,
Jaliya