Monthly Archives: July 2020

Dependency Injection and Blazor

In a previous post Blazor routing and Navigation we injected the NavigationManager into out page using the following

@inject NavigationManager NavManager

So when we use @inject followed by the type we want injected, ASP.NET/Blazor will automatically supply the NavigationManager (assuming one exists).

Adding services

Ofcourse we can also add our own types/services to the DI container.

On a Blazor WebAssembly application, we can add types to the Program.cs, Main method, for example

public static async Task Main(string[] args)
{
   var builder = WebAssemblyHostBuilder.CreateDefault(args);
   // template generated code here

   // my custom DataService
   builder.Services.AddSingleton<IDataService, DataService>();

   await builder.Build().RunAsync();
}

In Blazor Server, we add our types to the Startup.cs, ConfigureServices method, for example

public void ConfigureServices(IServiceCollection services)
{
   // template generated code here

   // my custom DataService
   services.AddSingleton<IDataService, DataService>();
}

Service lifetime

In the examples in the previous section we added the service as a singleton.

  • Scoped – this is means the service is scoped to the connection. This is the preferred way to handle per user services – there is no concept of scope services in WebAssembly as obviously it’s a client technology at this point and already per user scoped
  • Singleton – As you’d expect, this is a single instance for the lifetime of the application
  • Transient – each request for a transient service will receive a new instance of the service
  • If you need access to service is a Component class, i.e. you’re creating your own IComponent you have mark a property with the InjectAttribute

    public class MyService
    {
       [Inject]
       IDataService DataService { get; set; }
    }
    

    Ofcourse constructor injection (my preferred way to do things) is also available, so we just write code such as this, assuming that MyService is created using the service container

    public class MyService
    {
    public MyService(IDataService dataService)
    {
    // do something with dataService
    }
    }

    Destructing in JavaScript

    In JavaScript/TypeScript, if you’re using the Prefer destructuring from arrays and objects (prefer-destructuring) eslint rule, you’ll want to use destructing syntax to get values from objects and arrays.

    If we imagine we have an object like this

    class Person
    {
       firstName: string;
       lastName: string;
    }
    

    The to get the firstName from a Person instance, we tend to use

    const firstName = person.firstName;
    

    Instead this rule prefers that we use the following syntax

    const { firstName } = person;
    

    If for some reason (for example in React if you’re destructing state which may have been changed) you have need to get the value using destructing syntax but assigned to a new variable/value name, then we use

    const { firstName: fname } = person;
    

    Configuration and Blazor

    In a previous post we looked at dependency injection within Blazor. One of the services available by default is an implementation of IConfiguration, hence to inject the configuration object we do the following

    @inject IConfiguration Configuration
    

    and we can interact with the configuration using a key, i.e.

    @Configuration["SomeKey"]
    

    For Blazor on the server we can simply add the key/value to the appsettings.json file, like this

    "SomeKey":  "Hello World" 
    

    By default Blazor WebAssembly does not come with an appsettings.json, so you’ll need to add one yourself. This file will need to be in the wwwroot folder as these files will be deployed at part of your client.

    You can put sensitive data in the server appsettings.json because it’s hosted on the server, do not put sensitive information in the appsettings.json for a WebAssembly/client otherwise this will be downloaded to the user’s machine.

    If you want to store more complicated data in the appsettings.json, for example a JSON object, you’ll need to create a class that looks like the data, for example if your appsettings.json had the following

    "Person": {
      "FirstName": "Scooby",
      "LastName": "Doo"
    } 
    

    So now we’ll need a class to match the structure of the data. The name of the class is not important, the structure is, so here we have

    public class MyPerson
    {
       public string FirstName { get; set; }
       public string LastName { get; set; }
    }
    

    Now to access this we need to use

    Configuration.GetSection("Person").Get<MyPerson>();
    

    References

    Carl Franklin’s Blazor Train: Configuration and Dependency Injection

    Adding images to your github README…

    Obviously there are several ways to add images to your GitHub README.md or other mark down files in GitHub.

    1. Check them into the repository that includes the README.md
    2. Use a CDN or other file storage outside of GitHub
    3. Attach the image to an issue within your repository

    If you are going to use the first option, then there’s an obvious downside, in that the image(s) are now part of your repo. and will add to the overall download, clone, fork etc.

    Obviously the second option is great if you have CDN access of other filer space.

    The third option is presented on GitHub Tricks: Upload Images & Live Demos and simply requires

    1. Create an issue in your repo
    2. Drag and drop the image from File Explorer (or the likes) into the comment section of the issue
    3. When the link is updated in the comment, i.e. you see the image, copy the link using your browser (i.e. right mouse click, copy link)
    4. Now use this link in your markdown

    To use the link in GitHub markdown just use

    ![You Text](Image Url)
    

    Generating IL using C#

    Note: This is an old post I had sitting around for a couple of years, I’m not sure how complete or useful it is, but better being published than hidden away and it might be of use at some point.

    There are different ways to dynamically generate code for .NET, using tools such as T4, custom code generators run via target builds etc. Then there’s creating your assembly, modules, types etc. via IL. I don’t mean literally write IL files but instead generating your IL via C# using the ILGenerator class and Emit methods.

    I wanted to write a factory class that worked a little like Refit in that you define the interface and Refit “magically” creates an implementation to the interface and calls boilerplate code to inject and/or do the work required to make the code work.

    Refit actually uses build targets and code generation via GenerateStubsTask and InterfaceStubGenerator not IL generation.

    IL is not really a simple way to achieve these things (source generators, currently in previous, would be far preferable) but maybe in some situations IL generation suits your requirements and I thought it’d be an interesting thing to try anyway.

    Use case

    What I want to do is allow the developer to create an interface which contains methods (we’re only going to support “standard” methods at this point). The methods may take multiple arguments/parameters and must return Task (for void) or Task of T (for return values). Just like Refit, the idea would be that the developer marks methods in the interface with attributes which then tell the factory class what code to generate for the implementation.

    All very much along the lines of Refit.

    Starting things off by creating our Assembly

    We’re going to need to create an Assembly, at runtime, to host our new types, so the first thing we do is, using the domain of the current thread we’ll use the method DefineDynamicAssembly, pass in both an AssemblyName and AssemblyBuilderAccess parameter which creates an AssemblyBuilder. This becomes the starting point for the rest of our builders and eventually our IL code.

    Note: If you want to save the assembly to disk, which is very useful for debugging by inspecting the generated code using ILSpy or the likes, then you should set the AssemblyBuilderAccess to AssemblyBuilderAccess.RunAndSave and supply the file path (not the filename) as the fourth argument to DefineDynamicAssembly.

    Before we get into this code further, let’s look at a simple interface which will be our starting point.

    public interface IService
    {
       Task<string> GetName();
    }
    

    Whilst the aim, eventually, is to include attributes on our interface and return different generic types, for this post we’ll not get into this, but instead simply generate an implementation which ignores the arguments passed and expects either a return of Task or Task<string>.

    Let’s create our assembly – here’s the code for the TypeGenerator class.

    public class TypeGenerator
    {
       private AssemblyBuilder _assemblyBuilder;
       private bool _save;
       private string _assemblyName;
    
       public TypeGenerator WithAssembly(string assemblyName, string filePath = null)
       {
          var currentDomain = Thread.GetDomain();
          _assemblyName = assemblyName;
          _save = !String.IsNullOrEmpty(filePath);
    
          if (_save)
          {
             _assemblyBuilder = currentDomain.DefineDynamicAssembly(
                new AssemblyName(_assemblyName),
                   AssemblyBuilderAccess.RunAndSave,
                      filePath);
          }
          else
          {
             _assemblyBuilder = currentDomain.DefineDynamicAssembly(
                new AssemblyName(_assemblyName),
                   AssemblyBuilderAccess.Run);
          }
          return this;
       }
    
       public static TypeGenerator Create()
       {
          return new TypeGenerator();
       }
    }
    

    The code above will not actually save the assembly but is part of the process we need to go through to actually save it. Let’s add a save method which will actually save the assembly to disk.

    public TypeGenerator Save()
    {
       if (!String.IsNullOrEmpty(_assemblyName))
       {
          _assemblyBuilder.Save(_assemblyName);
       }
       return this;
    }
    

    Note: we’ll also need to assign the assembly name to the Module which we’re about to create.

    Now we need a Module

    Creating the module is simply a case of calling DefineDynamicModule on the AssemblyBuilder that we created, this will give us a ModuleBuilder which is where we’ll start generating our type code.

    As noted, if we are saving the module then we also need to assign it the assembly name, so here’s the code for creating the ModuleBuilder

    public TypeGenerator WithModule(string moduleName)
    {
       if (_save)
       {
          _moduleBuilder = _assemblyBuilder.DefineDynamicModule(
             moduleName, _assemblyName);
       }
       else
       {
          _moduleBuilder = _assemblyBuilder.DefineDynamicModule(
             moduleName);
       }
       return this;
    }
    

    Creating our types

    Considering this post is about IL code generation, it’s taken a while to get to it, but we’re finally here. We’ve created the assembly and within that a module. Our current implementation for generating a type will take the interface as a generic parameter (only interfaces will be handled), here’s the method

    public TypeGenerator WithType<T>()
    {
       var type = typeof(T);
    
       if (type.IsInterface)
       {
          EmitTypeFromInterface(type);
       }
    
       return this;
    }
    

    The EmitTypeFromInterface will start by defining a new type using the ModuleBuilder. We’ll create a name based upon the interface type’s name. Obviously the name needs to be unique. To make things simple we’ll just prefix the text “AutoGenerated”, hence type IService will become implementation AutoGeneratedIService. We’ll also need to set up the TypeAttributes to define our new type as a public class and in our case ensure the new type extends the interface. Here’s the code to generate a TypeBuilder (and also create the constructor for the class)

    private void EmitTypeFromInterface(Type type)
    {
       _typeBuilder = _moduleBuilder.DefineType($"AutoGenerated{type.Name}",
          TypeAttributes.Public |
          TypeAttributes.Class |
          TypeAttributes.AutoClass |
          TypeAttributes.AnsiClass |
          TypeAttributes.BeforeFieldInit |
          TypeAttributes.AutoLayout,
          null, new[] { type });
    
    
       var constructorBuilder =
          _typeBuilder.DefineDefaultConstructor(
             MethodAttributes.Public |
             MethodAttributes.SpecialName |
             MethodAttributes.RTSpecialName);
    
       // insert the following code snippets here
    }
    

    Implementing our methods

    Obviously an interface requires implementations of it’s methods – yes you can actually save the assembly without supplying the methods and will get a TypeLoadException stating that the new type does not have an implementation for the method.

    In the code below we’ll look through the methods on the interface type and using the TypeBuilder we’ll create a MethodBuilder per method which will have the same name, return type and parameters and will be marked as public and virtual, from this we’ll finally get to emit some IL using the ILGenerator. Here’s the code

    foreach (var method in type.GetMethods())
    {
       var methodBuilder = _typeBuilder.DefineMethod(
          method.Name,
          MethodAttributes.Public |
          MethodAttributes.Virtual,
          method.ReturnType,
          method.GetParameters().Select(p => p.ParameterType).ToArray());
    
       var ilGenerator = methodBuilder.GetILGenerator();
    
       // IL Emit code goes here
    }
    

    A very basic overview or writing IL code

    We can generate IL code using an ILGenerator and Emit methods from a C# application (for example). We can also write IL directly as source code files. For example, create a file test.il

    Now add the following code

    .assembly MyAssembly
    {
    }
    
    .method void Test()
    {
    .entrypoint
    ret
    }
    

    The text preceded by the . are directives for the IL compiler (ILASM which comes with Visual Studio). Within the file we’ve firstly declared an assembly named MyAssembly. Whilst this file would compile without the .assembly, it will not run and will fail with a BadImageFormatException.

    Next we define a method (using the .method directive) named Test. The .entrypoint declares this is the entry point to our application (as this will compile to an EXE). Hence unlike C# where we use Main as the entry point, any method may be the entry point but only one method may be marked as the entry point.

    To create a correctly formed method we also need the last line code to be a ret.

    If you now compile this file using

    ilasm test.il
    

    You might notice that ilasm outputs the warning Non-static global method ‘Test’, made static. Obviously in C# our entry method would normally be a static method. Simply add the keyword static as below

    .method static void Test()
    {
    .entrypoint
    ret
    }
    

    Let’s now turn this little IL application into the classic Hello World by calling the Console.WriteLine method.

    If you’ve ever written any assembly code you’ll know we pass arguments to subroutines by placing the arguments on the stack and then the callee will pop the expected number of arguments. So to output a string, we’ll need to push it onto the stack – in this case we use ldstr which specifically handles strings.

    Console.WriteLine is available in the System namespace within mscorlib, and to invoke a method we’ll need to call it specifying the overload (if any) to use along with a fully qualified name, hence our Test method becomes

    .method static void Test() 
    {
    .entrypoint
    
    ldstr "Hello World"
    call void [mscorlib]System.Console::WriteLine(class System.String)
    ret
    }
    

    The easiest way to learn IL is to look at decompilation from tools such as ildasm, ILSpy, Reflector or dotPeek, write code you wish to generate IL for, compile then decompile with one of these tools to see what’s going on.

    Using .mailmap

    When we create a commit in Git we get the author field listing the author’s name and email address. There are occasions where maybe an author is using different email addresses or names and we’d like to “fix” the commits to show the current or correct information for a commit.

    Just add a file named .mailmap into the root folder of your project which contains the name of an author along with any email addresses that are to link to that author, for example

    Bruce Dickinson  <bruce@im.com> <bruce@samson.net>
    

    See mailmap for more information.

    Editorconfig

    When we’re collaborating with other developers, whether you’re writing JavaScript, C~ or whatever, it’s useful (some may say essential) to create a coding style that all developers adhere to. After all, one of the aims of collaboration is that you shouldn’t really be able to tell who wrote what code just by the code style.

    With web development it’s not unusual to enforce code style etc. with eslint & prettier but this is often shown as a warning when things are working against the style or in some cases, these changes are only applied upon committing the source code. It’s be much better if we could have the editor automatically work the same, for things like indent styles (for example).

    This is where the .editorconfig comes in. A file you should commit with your source code and is supported by Visual Code, Visual Studio, JetBrains IDE’s etc.

    I’ll be honest, the main reason I use the .editorconfig is to configure my editors to use the same indent_size. Here’s a basic .editorconfig file

    root=true
    
    [*]
    indent_size = 2
    end_of_line = lf
    

    Visual Code has an extension available named EditorConfig which can be used to generate a bare bones .editorconfig for you. Visual Studio has a file template, just add a new file to your project using the Add | New Item… context menu and search for editorconfig. Selecting the editorconfig (.NET) will populate the .editorconfig with lots of options set for various .NET languages.

    If you have an .editorconfig file in the root of your project it will be applied to all sub-folders unless overridden by another .editorconfig in one or more of these folders.

    If you want to override some, but not all options within the root .editorconfig then just put those additions/changes in the file and ensure

    root = true
    

    exists in the root level file.

    As you’d expect the .editorconfig is read top to bottom, hence if you have a duplicate key later on in the file this will override any previous value.

    References

    EditorConfig
    Create portable, custom editor settings with EditorConfig

    Targeting multiple frameworks in .NET

    In this post we’re going to look at the process of targeting multiple .NET frameworks.

    You may have seen this concept when installing nuget packages, viewing the package itself and noting that packages have lib folders which (in some cases) have multiple names such as net35, net40 etc. Hence having assemblies which are compatible with those versions of .NET.

    For example, the packages/Castle.Core.4.2.1/lib folder contains

    • net35
    • net40
    • net45
    • netstandard1.3

    The names are based upon, what’s called, the TargetFrameworkMoniker (or TFM for short), see Target frameworks in SDK-style projects for both a list of TFM’s as well as a Microsoft post of targeting multiple frameworks.

    It looks like we need to be using the new SDK csproj files which we can create using either the dotnet CLI or by creating a .NET core or standard projects (or you can use conversion tools).

    Let’s therefore walk through the steps for setting up a Class Library that can target a few different frameworks.

    • Create a .NET standard class library
    • Open the csproj file in Visual Studio or your preferred editor
    • Change the following
      <Project Sdk="Microsoft.NET.Sdk">
      
        <PropertyGroup>
          <TargetFramework>netstandard2.0</TargetFramework>
        </PropertyGroup>
      
      </Project>
      

      to use TargetFrameworks (plural) and add any frameworks you’re targeting delimited by a semi-colon, i.e.

      <Project Sdk="Microsoft.NET.Sdk">
      
        <PropertyGroup>
          <TargetFrameworks>netstandard2.0;net45</TargetFrameworks>
        </PropertyGroup>
      
      </Project>
      
    • Save and if necessary reload Visual Studio to see the effects of these changes.

    If all went well you should see The Dependencies section of your project (within Visual Studio) lists both

    • .NETFramework 4.5
    • .NETStandard 2.0

    If you now build your project you’ll get both net45 and netstandard2.0 folders/builds in the bin/Debug and bin/Release folders.

    We can now either explicitly add assemblies or packages to our framework specific dependencies and ofcourse, by using preprocessor symbols such as NETSTANDARD2_0 and NETFRAMEWORK or NET45 we can begin to conditionally compiler code for the different target frameworks.

    We can add nuget to install package and add references to our multiple targets, but in some circumstances we might need to be more specific about which package is referenced by which target.

    In such cases we can add the reference to the application using Visual Studio and then edit the csproj ourselves to add a Condition around the reference, for example

    <ItemGroup Condition=" '$(TargetFramework)' == 'net45' ">
      <PackageReference Include="Microsoft.Net.Http" Version="2.2.29" />
    </ItemGroup>
    

    In this example, only the .NET 3.4 target will get the reference added to it.

    Now we’ve seen how to add conditions to our csproj we can also define constants for use also (or ofcourse using the project properties tab within Visual Studio to add these), for example

    <PropertyGroup Condition=" '$(TargetFramework)' == 'netstandard2.0'">
       <DefineConstants>SOME_CONSTANT</DefineConstants>
    </PropertyGroup>
    

    References

    Target frameworks in SDK-style projects
    Support multiple .NET versions
    .NET Standard

    ASP.NET Core and Web API

    In the past I’ve looked at ServiceStack for developing REST services however there are alternatives to ServiceStack, one of which is Web Api. Let’s create a simple starter project using ASP.NET Core and Web Api to implement our services.

    • Create a new ASP.NET Core Web Application
    • Select API

    The generated service supplies a Controllers/ValuesController.cs file which includes a controller class with the various REST methods.

    Controllers partition your application’s API, so for example you might have an AuthenticateController solely for authentication methods and another controller for CRUD operations on a datasource.

    For example this is a simple AuthenticateController class

    [Route("[controller]")]
    [ApiController]
    public class AuthenticateController : ControllerBase
    {
       [HttpPost]
       public ActionResult<AuthenticateReponse> Post([FromBody] User user)
       {
          return new AuthenticateReponse
          {
             Token = $"{user.Name}|1234"
          };
       }
    }
    

    Here, the Route is set to [controller] so our URL would be http://localhost/Authenticate. In this example we intend for the user to send data within an HTTP POST method, passing a User object (which is a simple name/password object). An AuthenticateResponse object is return via the ActionResult.

    The ActionResult return value allows us to return HTTP 200 OK or using subclasses such as BadRequest for an HTTP 400 and there are other derivations for other HTTP responses.

    The Action<> allows us to return a 200 OK without the need of using the Ok() method, although this can be used if preferred.

    When using different return responses it’s good to also document these by adding

    [ProducesResponseType(400)]
    

    This indicates that the method may return an HTTP 400. This is useful for use with Open API tools such as Swagger.

    As can be seen in the Post method, the User object is expected within the method’s body and the HttpPost attribute declare the method uses HTTP POST, the method name is superfluous in terms of the REST API.

    The different HTTP methods

    The code generated by the template creates a ValuesController with various HTTP methods, which I’ll recreate here for reference

    HTTP GET without URL parameters

    [HttpGet]
    public ActionResult<IEnumerable<string>> Get()
    {
       return new string[] { "value1", "value2" };
    }
    

    HTTP GET with URL parameters

    [HttpGet("{id}")]
    public ActionResult<string> Get(int id)
    {
       return "value";
    }
    

    HTTP POST without URL parameters

    [HttpPost]
    public void Post([FromBody] string value)
    {
    }
    

    HTTP PUT with URL parameters

    [HttpPut("{id}")]
    public void Put(int id, [FromBody] string value)
    {
    }
    

    HTTP DELETE with URL parameters

    [HttpDelete("{id}")]
    public void Delete(int id)
    {
    }
    

    HTTP HEAD

    [HttpGet, HttpHead]
    public IActionResult Head()
    {
       return Ok();
    }
    

    We would request the headers using HttpHead along with an HttpGet.

    HTTP PATCH

    [HttpPatch]
    public IActionResult Patch()
    {
       return Ok();
    }
    

    Adding Swagger support

    As per ASP.NET Core Web API help pages with Swagger / OpenAPI we can add Swagger support using either Swashbuckle.AspNetCore or NSwag (there may be others). Both are simple to add to our project.