.NET Readings

Roundup #53: .NET Core 3 Preview 9, Improved NuGet Search, Prefer ValueTask to Task, .NET Core API Performance

.NET Core 3 is getting closer! Want to know what’s new in Preview 9?


Navigating the .NET Ecosystem

In the spirit of .NET Core 3, it’s good to learn how we get here. This post covers past, present and future of .NET. And with that, C# and .NET Foundation as well!


New in ASP.NET Core 3: Service provider validation

Still about .NET Core 3 … I’m pretty sure everyone has come across situation where you deploy your app and find out you forgot to register one of the dependency in the IoC container. Well, with .NET Core 3, you can avoid this.


What’s new in Microsoft .Net Framework 4.8

With all the things going on in .NET Core development, let’s not forget about .Net Framework! Well, what’s new? Couple BCL stuff, fix on CLR issues, hashing algorithm, WPF and WCF stuff, many more.


Use Performance Counters in .NET to measure Memory, CPU, and Everything – Full Guide

I personally am dealing with memory issue in .Net Core application that we built. Michael laid it out on how you could user counters to measure not just memory, but CPU and everything in between.


Autofac Keyed Service Example

Note: Tested on Autofac 4.9.2.

Autofac Keyed Services provide convenience way to register multiple types of same interface with key identifier, see the documentation here.

It’s very useful feature when we want to choose between different implementations of same interface. See below for example:

`WebApiConfig.cs`
This is where we register our type in Autofac container.

var builder = new ContainerBuilder();

builder.RegisterType<CorporateService>()
    .As<IService>()
    .Keyed<IService>("Corporate");
builder.RegisterType<SchoolService>()
    .As<IService>()
    .Keyed<IService>("School");

GlobalContainer.Container = builder.Build();

`GlobalContainer.cs`
This is global object to store our container for resolving type later in application lifecycle.

using Autofac;

namespace QC
{
    public class GlobalContainer
    {
        public static IContainer Container { get; set; }
    }
}

`IService.cs`
This is sample service interface – don’t copy, make your own.

namespace QC.Service
{
    public interface IService
    {
        double GetRate();
    }
}

`CorporateService.cs`
This is sample service interface implementation – don’t copy, make your own.

namespace QC.Service
{
    public class CorporateService : IService
    {
        public double GetRate()
        {
            return 15;
        }
    }
}

`SchoolService.cs`
This is sample service interface implementation – don’t copy, make your own.

namespace QC.Service
{
    public class SchoolService : IService
    {
        public double GetRate()
        {
            return 10;
        }
    }
}

There are 2 options to resolve `IService` to type we desired (ie: Corporate or School).

1. Resolving Explicitly.
Documentation.

`CustomerController.cs`
Sample controller that choose which service to initiate.

using Autofac;
using QC.Service;
using System.Web.Http;

namespace QC.Controllers
{
    public class CustomerController : ApiController
    {
        [HttpGet]
        public IHttpActionResult GetRate()
        {
            // In real-world, we would have business logic to determine which service to initiate
            var service = GlobalContainer.Container.ResolveKeyed<IService>("Corporate");

            var rate = service.GetRate();
            return this.Ok(rate); // Return 15
        }
    }
}

2. Resolving with an Index (recommended).
Documentation.

`CustomerController.cs`

using Autofac.Features.Indexed;
using QC.Service;
using System.Web.Http;

namespace QC.Controllers
{
    public class CustomerController : ApiController
    {
        private readonly IIndex<string, IService> serviceIndexes;
        private readonly IService service;

        public CustomerController(IIndex<string, IService> serviceIndexes)
        {
            this.serviceIndexes = serviceIndexes;

            // In real-world, we would have business logic to determine which service to initiate
            this.service = this.serviceIndexes["Corporate"];
        }

        [HttpGet]
        public IHttpActionResult GetRate()
        {
            var rate = this.service.GetRate();
            return this.Ok(rate); // Return 15
        }
    }
}

Angular 6 Sharing Service… or not…

Different ways to share Service instance in Angular 6.

Service instance shared across entire application.

  • Declare `providedIn: ‘root’` property of `@Injectable` decorator in the Service. Then inject service to component’s constructor as usual.
  • import { Injectable } from '@angular/core';
    
    @Injectable({
      providedIn: 'root'
    })
    export class Service1Service {
      constructor() {
      }
    }
    
  • Declare service in `providers` property of `@NgModule` decorator in highest module (Ie: app.module.ts). Then inject service to component’s constructor as usual.
  • app.module.ts

    @NgModule({
        declarations: [...],
        imports: [...]
        providers: [Service1Service]
    })
    

Service instance shared across module.
Declare service in `providers` property of `@NgModule` decorator in any module except the highest module (Ie: user.module.ts, order.module.ts, etc). Then inject service to component’s constructor as usual.

user.module.ts

@NgModule({
    declarations: [...],
    imports: [...]
    providers: [Service1Service]
})

Service instance in every single component (not shared).
Declare service in `providers` property of `@Component` decorator in any component. Then inject service to component’s constructor as usual.

component1.component.ts

import { Component } from '@angular/core';
import { Service1Service } from '../service1.service';

@Component({
  selector: 'app-component1',
  templateUrl: './component1.component.html',
  styleUrls: ['./component1.component.css'],
  providers: [Service1Service]
})
export class Component1Component {
  constructor(private service1: Service1Service) {
  }
}

Dependency Injection in Web API With Unity IoC

WebApiConfig.cs

public static class WebApiConfig
{
    public static void Register(HttpConfiguration config)
    {
        var container = new UnityContainer();
        container.RegisterType<IProductRepository, ProductRepository>();
        config.DependencyResolver = new UnityResolver(container);

        // Other Web API configuration not shown.
    }
}

Global.asax.cs

protected void Application_Start()
{
    // Some code here...

    WebApiConfig.Register(GlobalConfiguration.Configuration);

    // Some code here...
}

Version attow: Unity 3, Web API 2

Unity Dependency Injection in ASP.NET MVC Authorize Attribute

Often times, we need custom Authorize attribute used in ASP.NET MVC to customized authorization using our own authorize / authentication service. And with that, we need to inject dependency into the attribute.

In C#, only certain type can be passed into an attribute. To get dependency in an attribute: DependencyResolver.Current.GetService()

public class MyAuthorizationAttribute : AuthorizeAttribute
{
    public IMyAuthService myAuthService { get; set; }

    public PartDAuthorizationAttribute()
    {
        myAuthService = DependencyResolver.Current.GetService<IMyAuthService>();
    }

    public override void OnAuthorization(AuthorizationContext filterContext)
    {
        if (filterContext.HttpContext.User.Identity.IsAuthenticated)
        {
            bool auth = myAuthService.IsUserAuthorized();
            if (!auth)
            {
                HandleUnauthorizedRequest(filterContext);
            }
        }
        else
        {
            HandleUnauthorizedRequest(filterContext);
        }
    }
}

Code is written for Unity 3.0 and ASP.NET MVC 4

Dependency Inversion X Inversion Control X Dependency Injection

Dependency Inversion Principle
Definition: Instead of lowel level modules defining an interface that higher level modules depend on, higher level modules define an interface that lower level modules implement.
Example: portable chargeable devices, the copy program (read and write)

Inversion of Control

  • Interface inversion
    The user of the class defines the interface
    Interface should have more than 1 implementation
  • Flow inversion
    Procedural VS Event driven
  • Creation / binding inversion
    Creating objects outside of the class they are being used in.

Dependency Injection
A type of IOC where we move the creation and binding of a dependency outside of the class that depends on it.
Example: packing a lunch VS lunch is provided.

  • Constructor Injection
    Pass dependency into dependent class via constructor.
  • Setter Injection
    Create a setter on the dependent class and use the setter to set the dependency.
  • Interface Injection
    Dependent class implements an interface. Injector uses the interface to set the dependency.

Dependency Injection Structure

Highly coupled dependency

public class VerySimpleStockTraderImpl : IAutomatedStockTrader
{
    private IStockAnalysisService analysisService = new StockAnalysisServiceImpl();
    private IOnlineBrokerageService brokerageService = new NewYorkStockExchangeBrokerageServiceImpl();

    public void executeTrades()
    {
        for (String stockSymbol : brokerageService.getStockSymbols())
        {
             double askPrice = brokerageService.getAskingPrice(stockSymbol);
             double estimatedValue = analysisService.getEstimatedValue(stockSymbol);
             if (askPrice < estimatedValue)
             {
                  brokerageService.putBuyOrder(stockSymbol, 100, askPrice);
             }
        }
    }
}

public class MyApplication
{
    public static void main(String[] args)
    {
        IAutomatedStockTrader stockTrader = new VerySimpleStockTraderImpl();
        stockTrader.executeTrades();
    }
}

Manually injected dependency

public class VerySimpleStockTraderImpl : IAutomatedStockTrader
{
    private IStockAnalysisService analysisService;
    private IOnlineBrokerageService brokerageService;

    public VerySimpleStockTraderImpl(IStockAnalysisService analysisService, IOnlineBrokerageService brokerageService)
    {
        this.analysisService = analysisService;
        this.brokerageService = brokerageService;
    }

    public void executeTrades()
    {
        ....
    }
}

public class MyApplication
{
    public static void main(String[] args)
    {
        IStockAnalysisService analysisService = new StockAnalysisServiceImpl();
        IOnlineBrokerageService brokerageService = new NewYorkStockExchangeBrokerageServiceImpl();

        IAutomatedStockTrader stockTrader = new VerySimpleStockTraderImpl(analysisService, brokerageService);
        stockTrader.executeTrades();
    }
}

Automatically injected dependency

public class VerySimpleStockTraderImpl : IAutomatedStockTrader
{
    private IStockAnalysisService analysisService;
    private IOnlineBrokerageService brokerageService;

    public VerySimpleStockTraderImpl(IStockAnalysisService analysisService, IOnlineBrokerageService brokerageService)
    {
        this.analysisService = analysisService;
        this.brokerageService = brokerageService;
    }

    public void executeTrades()
    {
        ....
    }
}

public class MyApplication
{
    public static void main(String[] args)
    {
        IAutomatedStockTrader stockTrader = (IAutomatedStockTrader)DependencyManager.create(typeof(IAutomatedStockTrader));
        stockTrader.executeTrades();
    }
}

Source: Wikipedia