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<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<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<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

Thursday, June 14, 2018

Session: ASP.NET Core 2.1: ActionResult<T> and HttpClientFactory at Sri Lanka Developer Forum

Delivered an hour-long session at Sri Lanka Developer Forum titled ASP.NET Core 2.1: ActionResult<T> and HttpClientFactory. Actually, this was a cover-up session, the original speaker couldn’t make it to deliver the session. And this is the very first session that I did using someone else's laptop as my laptop had trouble connecting to the projector.

There was no time to prepare the slides, it was purely a hands-on session. There I demoed the use of ActionResult<T> and HttpClientFactory which was released with ASP.NET Core 2.1. And there were a lot of questions in overall .NET Core and ASP.NET Core.

Glad the session went well.

More information,

Happy Coding.

Regards,
Jaliya

Thursday, June 7, 2018

C#: Getting Power Set of Given Set of Numbers

This is a quick post on how you can calculate the Power Set of given numbers.

Let’s consider the following array.
int[] numbers = new int[] { 1, 2, 3 };
The Power Set of above would be as follows.
{}
{1}
{2}
{1,2}
{3}
{1,3}
{2,3}
{1,2,3}
Count of Power Set is 1 << CountOfNumbers (or 2 ^ CountOfNumbers).

Here is a simple method to get the Power Set of given integer array.
static IEnumerable<IEnumerable<int>> GetPowerSet(int[] numbers)
{
    List<List<int>> outerList = new List<List<int>>();
 
    int permutationsCount = 1 << numbers.Length;
    int[] permutationNumbers = Enumerable.Range(0, permutationsCount).ToArray();
 
    for (int i = 0; i < permutationsCount; i++)
    {
        List<int> innerList = new List<int>();
 
        for (int j = 0; j < numbers.Length; j++)
        {
            if ((permutationNumbers[i] & (1 << j)) != 0)
            {
                innerList.Add(numbers[j]);
            }
        }
 
        outerList.Add(innerList);
    }
 
    return outerList;
}
We can refactor the code to use LINQ and eliminate some line of codes.
static IEnumerable<IEnumerable<int>> GetPowerSet(int[] numbers)
{
    IEnumerable<IEnumerable<int>> permutations = from permutation in Enumerable.Range(0, 1 << numbers.Length)
                                                 select
                                                     from index in Enumerable.Range(0, numbers.Length)
                                                     where (permutation & (1 << index)) != 0
                                                     select numbers[index];
    return permutations;
}

Happy Coding.

Regards,
Jaliya

Wednesday, June 6, 2018

ASP.NET Core 2.1: HttpClientFactory

One of the features that got released with ASP.NET Core 2.1 is HttpClientFactory. In this post let’s see how we can use HttpClientFactory in an ASP.NET Core 2.1 application.

There are basically three ways.
  1. HttpClientFactory directly
  2. Named Clients
  3. Typed Clients
Let’s have a look at them with sample use.

1. HttpClientFactory directly

Registration
services
    .AddHttpClient();
Use
public class ValuesController : ControllerBase
{
    private readonly IHttpClientFactory httpClientFactory;
 
    public ValuesController(IHttpClientFactory httpClientFactory)
    {
        this.httpClientFactory = httpClientFactory;
    }
 
    [HttpGet]
    public async Task<ActionResult> Get()
    {
        var client = httpClientFactory.CreateClient();
        client.BaseAddress = new Uri("http://myblog.blogspot.com");
        // TODO: Client configuration
 
        string result = await client.GetStringAsync("/");
 
        return Ok(result);
    }
}

2. Named Clients

Registration
services
    .AddHttpClient()
    .AddHttpClient("BlogClient", client =>
    {
        client.BaseAddress = new Uri("http://myblog.blogspot.com");
        // TODO: Client configuration
    });
Use
public class ValuesController : ControllerBase
{
    private readonly IHttpClientFactory httpClientFactory;
 
    public ValuesController(IHttpClientFactory httpClientFactory)
    {
        this.httpClientFactory = httpClientFactory;
    }
 
    [HttpGet]
    public async Task<ActionResult> Get()
    {
        var client = httpClientFactory.CreateClient("BlogClient");
 
        string result = await client.GetStringAsync("/");
 
        return Ok(result);
    }
}
The only change is, instead of CreateClient(), I am calling CreateClient(clientName) which I have registered in ConfigureServices method.

3. Typed Clients

Consider the following implementation.
public class BlogClient
{
    public HttpClient Client { get; set; }
 
    public BlogClient(HttpClient client)
    {
        client.BaseAddress = new Uri("http://myblog.blogspot.com");
        // TODO: Client configuration
 
        this.Client = client;
    }
}
Registration
services
    .AddHttpClient()
    .AddHttpClient("BlogClient", client =>
    {
        client.BaseAddress = new Uri("http://myblog.blogspot.com");
        // TODO: Client configuration
    })
    .AddTypedClient<BlogClient>();
Use
public class ValuesController : ControllerBase
{
    private readonly BlogClient blogClient;
 
    public ValuesController(BlogClient blogClient)
    {
        this.blogClient = blogClient;
    }
 
    [HttpGet]
    public async Task<ActionResult> Get()
    {
        string result = await this.blogClient.Client.GetStringAsync("/");
 
        return Ok(result);
    }
}
Alternatively, you can define a contract.
public interface IBlogClient
{
    HttpClient Client { get; set; }
}
 
public class BlogClient : IBlogClient
{
    public HttpClient Client { get; set; }
 
    public BlogClient(HttpClient client)
    {
        client.BaseAddress = new Uri("http://myblog.blogspot.com");
        // TODO: Client configuration
 
        this.Client = client;
    }
}
Registration
services
    .AddHttpClient()
    .AddHttpClient("BlogClient", client =>
    {
        client.BaseAddress = new Uri("http://myblog.blogspot.com");
        // TODO: Client configuration
    })
    .AddTypedClient<BlogClient>()
    .AddTypedClient<IBlogClient, BlogClient>();
Use
public class ValuesController : ControllerBase
{
    private readonly IBlogClient blogClient;
 
    public ValuesController(IBlogClient blogClient)
    {
        this.blogClient = blogClient;
    }
 
    [HttpGet]
    public async Task<ActionResult> Get()
    {
        string result = await this.blogClient.Client.GetStringAsync("/");
 
        return Ok(result);
    }
}
Happy Coding.

Regards.
Jaliya

Tuesday, May 29, 2018

Visual C# Technical Guru - April 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,
image
Visual C# Technical Guru - April 2018
Happy Coding.

Regards,
Jaliya

Thursday, May 17, 2018

ASP.NET Core 2.1: ActionResult<TValue>

ASP.NET Core 2.1 is almost released, we now have access to ASP.NET Core 2.1 RC1. Among other nice features like SignalR (Yes, SignalR is included in ASP.NET Core 2.1) which is getting shipped with ASP.NET Core 2.1, one of my favorites is the introduction of ActionResult<TValue>.

Consider the following API action with ASP.NET Core prior to 2.1.
public Employee Get(int id)
{
    Employee employee = null;
 
    // TODO: Get employee by Id
 
    return employee;
}
So this is very simple, and we are searching for an Employee by Id and returning an Employee. Having Employee is the return type here is very useful for things like documenting the API using Swagger for instance.

But this looks like a bad code, what if there is no Employee by given Id. In that we don’t usually return null, we return HTTP Status Code: NotFound.

But if we are to return that, we no longer can return an Employee type, we are returning an IActionResult. And the code changes to following.
public ActionResult Get(int id)
{
    Employee employee = null;
 
    // TODO: Get employee by Id
 
    if (employee == null)
    {
        return NotFound();
    }
 
    return Ok(employee);
}
Now there is no easy way to know what the encapsulated type of the result.

But we don’t have to face this situation any longer. ASP.NET Core 2.1 introduces this new return type ActionResult<TValue>.
public ActionResult<Employee> Get(int id)
{
    Employee employee = null;
 
    // TODO: Get employee by Id
 
    if (employee == null)
    {
        return NotFound();
    }
 
    return employee;
}
So here ActionResult<Employee> will either wrap Employee or ActionResult based on the result at runtime.

I like this very much, hope you all do!

Happy Coding.

Regards,
Jaliya

Wednesday, May 16, 2018

Entity Framework Core 2.1: Lazy Loading

Last week (to be exact 7th of May, 2018) Entity Framework Core 2.1 RC 1 was released to the public. And one of the features that got released with EF Core 2.1 was Lazy Loading of related data.

In this post, let’s see how you can use that feature.

Consider I have the following code with an EF Core version prior to 2.1.
public class Employee
{
    public int Id { get; set; }
    public string Name { get; set; }
    public virtual Department Department { get; set; }
}
 
public class Department
{
    public int Id { get; set; }
    public string Name { get; set; }
    public virtual ICollection<Employee> Employees { get; set; }
}
 
public class MyDbContext : DbContext
{
    public DbSet<Employee> Employees { get; set; }
    public DbSet<Department> Departments { get; set; }
 
    protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    {
        optionsBuilder
            .UseSqlServer(@"Server=.;Database=EfCoreLazyLoadingDemo;Trusted_Connection=True;");
    }
}
And I have some Departments and Employees in the database.

Departments
image
Departments
Employees
image
Employees
And I have the following code to print out different Departments and Employees of each of the Department.
static void Main(string[] args)
{
    using (MyDbContext context = new MyDbContext())
    {
        foreach (var department in context.Departments)
        {
            Console.WriteLine(department.Name);
            if (department.Employees != null)
            {
                foreach (var employee in department.Employees)
                {
                    Console.WriteLine($"--{employee.Name}");
                }
            }
        }
    }
}
So if you run this, you should be seeing something like below.
image
Output
No Employees were loaded, and to fix that, you will need to do something like below which is known as Eager Loading.
foreach (var department in context.Departments.Include(d => d.Employees))
Basically, the virtual properties have no effect unlike EF.

And to make Lazy Loading work, we need to update EF Core references to 2.1.0-rc1-final. And in addition, we need to install another package, Microsoft.EntityFrameworkCore.Proxies.

After packages are updated/installed, we have two ways.

1. UseLazyLoadingProxies

This is the easiest way, you just need to add UseLazyLoadingProxies to OnConfiguring override (or within AddDbContext).
public class MyDbContext : DbContext
{
    public DbSet<Employee> Employees { get; set; }
    public DbSet<Department> Departments { get; set; }
 
    protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    {
        optionsBuilder
            .UseLazyLoadingProxies()
            .UseSqlServer(@"Server=.;Database=EfCoreLazyLoadingDemo;Trusted_Connection=True;");
    }
}
And now following should be loading each Departments Employees.
foreach (var department in context.Departments)
image
Output
You don’t have to explicitly Include the Employees. But remember, navigational properties should be virtual.

2. Lazy-loading without proxies

This includes polluting your entities with additional code.
public class Employee
{
    private ILazyLoader _lazyLoader { get; set; }
 
    public Employee(ILazyLoader lazyLoader)
    {
        _lazyLoader = lazyLoader;
    }
 
    public int Id { get; set; }
    public string Name { get; set; }
 
    private Department _department;
    public Department Department
    {
        get => _lazyLoader?.Load(this, ref _department);
        set => _department = value;
    }
}
 
public class Department
{
    private ILazyLoader _lazyLoader { get; set; }
 
    public Department(ILazyLoader lazyLoader)
    {
        _lazyLoader = lazyLoader;
    }
 
    public int Id { get; set; }
    public string Name { get; set; }
 
    private ICollection<Employee> _employees;
    public virtual ICollection<Employee> Employees
    {
        get => _lazyLoader?.Load(this, ref _employees);
        set => _employees = value;
    }
}
Now when using this, you don’t need to have UseLazyLoadingProxies and navigation properties doesn’t need to be virtual. EF Core will be injecting ILazyLoader where it’s required, and he is going to load the related data.

This will also give us the following output.
image
Output
And before winding up, note, Lazy Loading should be used with care. It doesn’t matter whether it’s EF or EF Core, it can affect the performance big time.

Happy Coding.

Regards,
Jaliya

Tuesday, May 15, 2018

Dependency Injection in Blazor

[Content in this post is based on Blazor 0.3.0]

In my last post, I wrote about how you can get yourself started on Blazor. If you are new to Blazor, maybe you can read it first, so you can easily catch along with this. In this post let’s see how we can use Dependency Injection within Blazor.

DI is a first class citizen is Blazor meaning Blazor has DI built in.

If you have a look at the Program.cs of an Blazor application, you should be seeing this.
public class Program
{
    static void Main(string[] args)
    {
        var serviceProvider = new BrowserServiceProvider(services =>
        {
                
        });
 
        new BrowserRenderer(serviceProvider).AddComponent<App>("app");
    }
}
Now we have the following Interface and the implementation.

IMyService.cs
interface IMyService
{
    string Echo();
}

MyService.cs
public class MyService : IMyService
{
    public string Echo()
    {
        return "Hello Blazor";
    }
}

And say, I want to be able to use MyService.Echo() method in any of my component.

First what we need to do is register the service.
image
Service Registration
Here you can see that we can use the ServiceDescriptor to register the service mainly in three different ways, Scoped, Singleton and Transient.
  • Scope,d: Currently no scoping is supported. Behaves like Singleton.
  • Singleton: Single instance. When requested, everyone gets the same instance.
  • Transient: When requested, gets a new instance.
All these registrations are getting added into Blazor’s DI.

For the demo, I will use Singleton.
var serviceProvider = new BrowserServiceProvider(services =>
{
    services.Add(ServiceDescriptor.Singleton<IMyService, MyService>());
})

Now let’s see how we can make use of this. I am going to modify the index.cshtml file.

There is two ways to inject a service into a component.

1. Use @inject
@page "/"
 
@inject IMyService service
 
<h1>Hello, world!</h1>
<h3>@service.Echo()</h3>
 
Welcome to your new app.
 
<SurveyPrompt Title="How is Blazor working for you?" />

2. Use [Inject] attribute
@page "/"
 
<h1>Hello, world!</h1>
<h3>@service.Echo()</h3>
 
Welcome to your new app.
 
<SurveyPrompt Title="How is Blazor working for you?" />
 
@functions{     
   [Inject]     
   IMyService service { get; set; }
}
Both of the approaches will be giving us following.
image
Output
If you have a look at the FetchData.cshtml file which is getting added when we have created a Blazor project using Visual Studio, you must have noticed injecting of HttpClient.
@page "/fetchdata"
@inject HttpClient Http
Have you wondered where that is coming from. HttpClient  and IUriHelper (Service for working with URIs and navigation state) is by default configured for DI in Blazor.

Pretty straightforward, isn't it. Hope this helps!

Happy Coding.

Regards,
Jaliya