Sunday, 27 September 2020

Generic Memory Cache for .Net Framework

The following sample code shows how to create a Generic Memory Cache for .Net Framework. This allows you to cache specific items defined by a TCacheItemData type argument, i.e. caching same type of data such as instances of a class, or arrays of instances. Inside your .csproj you should see something like:
    
Over to the implementation. Since a memory cache is shared by possibly other applications, it is important to prefix your cached contents, i.e. prefix the the keys. This makes it easier to barrier the memory cache. Note though that some barriering is done accross processes of course, this is just to make it easier within your application and running process to group the cached elements with a prefix key used for the generic memory cache operations. Now over to the implementation.


using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Runtime.Caching;

namespace SomeAcme.SomeUtilNamespace
{
    /// <summary>
    /// Thread safe memory cache for generic use
    /// </summary>
    /// <typeparam name="TCacheItemData">Payload to store in the memory cache</typeparam>
    /// <remarks>Uses MemoryCache.Default which defaults to an in-memory cache. All cache items are prefixed with an 'import cache session guid' to compartmentalize
    /// multiple paralell importing sessions</remarks>
    public class GenericMemoryCache<TCacheItemData> where TCacheItemData : class
    {
        private readonly string _prefixKey;
        private readonly ObjectCache _cache;
        private readonly CacheItemPolicy _cacheItemPolicy;

        public GenericMemoryCache(string prefixKey, int defaultExpirationInSeconds = 0)
        {
            defaultExpirationInSeconds = Math.Abs(defaultExpirationInSeconds); //checking if a negative value was passed into the constructor.

            _prefixKey = prefixKey;
            _cache = MemoryCache.Default;
            _cacheItemPolicy = defaultExpirationInSeconds == 0
                ? new CacheItemPolicy { Priority = CacheItemPriority.NotRemovable }
                : new CacheItemPolicy
                { AbsoluteExpiration = DateTime.Now.AddSeconds(Math.Abs(defaultExpirationInSeconds)) };
        }

        /// <summary>
        /// Cache object if direct access is desired
        /// </summary>
        public ObjectCache Cache => _cache;

        public string PrefixKey(string key) => $"{_prefixKey}_{key}";


        /// <summary>
        /// Adds an item to memory cache
        /// </summary>
        /// <param name="key"></param>
        /// <param name="itemToCache"></param>
        /// <returns></returns>
        public bool AddItem(string key, TCacheItemData itemToCache)
        {
            try
            {
                if (!key.StartsWith(_prefixKey))
                    key = PrefixKey(key);

                var cacheItem = new CacheItem(key, itemToCache);
                _cache.Add(cacheItem, _cacheItemPolicy);
                return true;
            }
            catch (Exception err)
            {
                Debug.WriteLine(err);
                return false;
            }
        }

        public virtual List<T> GetValues<T>()
        {
            List<T> list = new List<T>();
            IDictionaryEnumerator cacheEnumerator = (IDictionaryEnumerator)((IEnumerable)_cache).GetEnumerator();

            while (cacheEnumerator.MoveNext())
            {
                if (cacheEnumerator.Key == null)
                    continue;
                if (cacheEnumerator.Key.ToString().StartsWith(_prefixKey))
                    list.Add((T)cacheEnumerator.Value);
            }
            return list;
        }

        /// <summary>
        /// Retrieves a cache item. Possible to set the expiration of the cache item in seconds. 
        /// </summary>
        /// <param name="key"></param>
        /// <returns></returns>
        public TCacheItemData GetItem(string key)
        {
            try
            {
                if (!key.StartsWith(_prefixKey))
                    key = PrefixKey(key);
                if (_cache.Contains(key))
                {
                    CacheItem cacheItem = _cache.GetCacheItem(key);
                    object cacheItemValue = cacheItem?.Value;
                    UpdateItem(key, cacheItemValue as TCacheItemData);
                    TCacheItemData item = _cache.Get(key) as TCacheItemData;
                    return item;
                }
                return null;
            }
            catch (Exception err)
            {
                Debug.WriteLine(err);
                return null;
            }
        }

        public bool SetItem(string key, TCacheItemData itemToCache)
        {
            try
            {
                if (!key.StartsWith(_prefixKey))
                    key = PrefixKey(key);
                if (GetItem(key) != null)
                {
                    AddItem(key, itemToCache);
                    return true;
                }

                UpdateItem(key, itemToCache);
                return true;
            }
            catch (Exception err)
            {
                Debug.WriteLine(err);
                return false;
            }
        }


        /// <summary>
        /// Updates an item in the cache and set the expiration of the cache item 
        /// </summary>
        /// <param name="key"></param>
        /// <param name="itemToCache"></param>
        /// <returns></returns>
        public bool UpdateItem(string key, TCacheItemData itemToCache)
        {
            if (!key.StartsWith(_prefixKey))
                key = PrefixKey(key);
            CacheItem cacheItem = _cache.GetCacheItem(key);
            if (cacheItem != null)
            {
                cacheItem.Value = itemToCache;
                _cache.Set(key, itemToCache, _cacheItemPolicy);
            }
            else
            {
                //if we cant find the cache item, just set the cache directly
                _cache.Set(key, itemToCache, _cacheItemPolicy);

            }
              return true;
           
        }

        /// <summary>
        /// Removes an item from the cache 
        /// </summary>
        /// <param name="key"></param>
        /// <returns></returns>
        public bool RemoveItem(string key)
        {
            if (!key.StartsWith(_prefixKey))
                key = PrefixKey(key);

            if (_cache.Contains(key))
            {
                _cache.Remove(key);
                return true;
            }
            return false;
        }

        public void AddItems(Dictionary<string, TCacheItemData> itemsToCache)
        {
            foreach (var kvp in itemsToCache)
                AddItem(kvp.Key, kvp.Value);
        }

        /// <summary>
        /// Clear all cache keys starting with known prefix passed into the constructor.
        /// </summary>
        public void ClearAll()
        {
            var cacheKeys = _cache.Select(kvp => kvp.Key).ToList();
            foreach (string cacheKey in cacheKeys)
            {
                if (cacheKey.StartsWith(_prefixKey))
                    _cache.Remove(cacheKey);
            }
        }

    }
}


Saturday, 11 July 2020

Adding live reloads developing Asp.Net Mvc Core razor views

To add live reloading when developing Asp.Net Core Views, it is recommended to upgrade to .Net Core 3.1. This makes it easier to add in the Nuget package for recompilation. In case you have a .Net Core 2 app, follow the MSDN guide here: https://docs.microsoft.com/en-us/aspnet/core/migration/22-to-30?view=aspnetcore-3.1&tabs=visual-studio After the app runs as .Net Core 3.1, run the following (procedure below is tested okay with VS 2019 and Chrome as the browser 'linked' to the reloading: Edit the .csproj file by selecting the project and right clicking and selecting Edit project file in VS 2019. Past in these two Nuget package references and run dotnet restore, then dotnet build and finally dotnet run.

  <ItemGroup>
    <PackageReference Include="Microsoft.AspNetCore.Mvc.Razor.RuntimeCompilation" Version="3.1.5" />
    <PackageReference Include="Microsoft.VisualStudio.Web.BrowserLink" Version="2.2.0" />
  </ItemGroup>

The runtime compilation and Browserlink should both be added. The first will rebuild your edited razor views (cshtml) and BrowserLink reloads your browser while debugging, after the razor view is updated. Also download this Visual Studio Extension, "Browser reload on save": https://marketplace.visualstudio.com/items?itemName=MadsKristensen.BrowserReloadonSave You will have to close all Visual Studio processes to start installing Mad Kristensen's browser extension. In your Startup class you should inside ConfigureServices add these two lines, specifying AddRazorRunitmeCompilation:
        services.AddRazorPages().AddRazorRuntimeCompilation();
        services.AddControllersWithViews().AddRazorRuntimeCompilation();
And finally at the top of the Configure method in the Startup class add in BrowserLink. Note, add this at the top of the Configure method such that the pipeline is adding BrowserLink correct.
  if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
                app.UseBrowserLink();
            }
Now, just start up your app with F5 and start editing a razor file. If all was set up correct, you should now see your razor view reload in the Browser. This makes it easier to edit and adjust razor views!

Monday, 29 June 2020

Adding Bootstrap 4 to Asp.Net Core MVC solution

To add Bootstrap 4 or newer to an Asp.NET Core MVC Solution, you can do this in the following manner if you use Visual Studio 2019 and .Net Core 3.1. Or at least have access to the 'Manage Client-side Libraries' functionality. Bootstrap is not supported in Nuget and definately not for .Net Core apps, so you need to add it manually using this. The Manage client-side libaries in Visual Studio adds a libman.json file. This is the Library Manager json file, similar to NPM based solutions package.json. Now add the following into libman.json:

{
  "version": "1.0",
  "defaultProvider": "cdnjs",
  "libraries": [
    {
      "library": "twitter-bootstrap@4.2.1",
      "destination": "wwwroot/lib/bootstrap",
      "files": [
        "js/bootstrap.bundle.js",
        "css/bootstrap.min.css"
      ]
    },
    {
      "library": "jquery@3.3.1",
      "destination": "wwwroot/lib/jquery",
      "files": [
        "jquery.min.js"
      ]
    }
  ]
}

This adds Bootstrap 4.2.1 and Jquery 3.3.1 into wwwroot lib folders for each library. Now in your _Layout.cshtml file (or the file you use as your Layout file), just drag bootstrap.min.css file and bootstrap.bundle.js files into that razor file. After you restart the solution, you should have Bootstrap 4 available into your Asp.Net Core MVC app! And if you want to add client side libraries using a GUI, select your project and choose then via right click Add->Client side library. Here you can search for client side libraries.

Wednesday, 17 June 2020

Multiple enum values set to same value codefix for VS

I created a new extension in Visual Studio today! The UniqueEnumValueFixer vs extension is now available here! https://marketplace.visualstudio.com/items?itemName=ToreAurstadIT.EXT001 The extension is actually a Code Fix for Visual Studio. It flags a warning to the developer if an enum contains multiple members mapped to the same value. Having a collision with values for enum causes ambiguity and confusion for the developer. An enum value has not got a single mapping from enum member to integer value. Example like this: Here we see that iceconverted is set to Fudge, which is the last of the colliding valued enum members. This gives code which is not clear and confusing and ambiguous. It is perfectly valid, but programmers will perhaps sigh a bit when they see enums with multiple members mapped to same value. The following sample code shows a violation of the rule:

    enum IceCream
    {
        Vanilla = 0, 
        Chocolate = 2,
        Strawberry = Vanilla,
        Peach = 2
    }

Here, multiple members are mapped to the same value in the enum. Strawberry and Vanilla points to the same value through assignment. And Peach is set to same value as Chocolate. The code fix will show enums containing the violation after compiling the solution in the Errors and Warnings pane of Visual Studio.

   public override void Initialize(AnalysisContext context)
        {
            // TODO: Consider registering other actions that act on syntax instead of or in addition to symbols
            // See https://github.com/dotnet/roslyn/blob/master/docs/analyzers/Analyzer%20Actions%20Semantics.md for more information
            context.RegisterSymbolAction(AnalyzeSymbol, SymbolKind.NamedType);

        }

        private static void AnalyzeSymbol(SymbolAnalysisContext context)
        {
            try
            {
                var namedTypeSymbol = (INamedTypeSymbol)context.Symbol;
                if (namedTypeSymbol.EnumUnderlyingType != null)
                {
                    var valueListForEnum = new List<Tuple<string, int>>();
                    //Debugger.Launch();
                    //Debugger.Break();
                    var typeResolved = context.Compilation.GetTypeByMetadataName(namedTypeSymbol.MetadataName) ?? context.Compilation.GetTypeByMetadataName(namedTypeSymbol.ToString());
                    if (typeResolved != null)
                    {
                        foreach (var member in typeResolved.GetMembers())
                        {
                            var c = member.GetType().GetRuntimeProperty("ConstantValue");
                            if (c == null)
                            {
                                c = member.GetType().GetRuntimeProperties().FirstOrDefault(prop =>
                                    prop != null && prop.Name != null &&
                                    prop.Name.Contains("IFieldSymbol.ConstantValue"));
                                if (c == null)
                                {
                                    continue;
                                }
                            }

                            var v = c.GetValue(member) as int?;
                            if (v.HasValue)
                            {
                                valueListForEnum.Add(new Tuple<string, int>(member.Name, v.Value));
                            }
                        }
                        if (valueListForEnum.GroupBy(v => v.Item2).Any(g => g.Count() > 1))
                        {
                            var diagnostic = Diagnostic.Create(Rule, namedTypeSymbol.Locations[0],
                                namedTypeSymbol.Name);
                            context.ReportDiagnostic(diagnostic);
                        }
                    }
                }
            }
            catch (Exception err)
            {
                Console.WriteLine(err);
            }

        }

The source code is available on Github here: https://github.com/toreaurstadboss/UniqueEnumValuesAnalyzer

Wednesday, 10 June 2020

Creating a self signed certificate with Powershell and preparing it for IIS

I just wrote an automated routine in Powershell to create a self signed certificate.
#Install-Module -Name 'WebAdministration'

Import-Module -Name WebAdministration

function AddSelfSignedCertificateToSSL([String]$dnsname, [String]$siteName='Default Web Site'){
 $newCert = New-SelfSignedCertificate -DnsName $dnsname -CertStoreLocation Cert:\LocalMachine\My
 $binding = Get-WebBinding -Name $siteName -Protocol "https"
 $binding.AddSslCertificate($newCert.GetCertHashString(), "My")
 $newCertThumbprint = $newCert.Thumbprint
 $sourceCertificate = $('cert:\localmachine\my\' + $newCertThumbprint)
 
 $store = new-object system.security.cryptography.X509Certificates.X509Store -argumentlist "Root", LocalMachine
 $store.Open([System.Security.Cryptography.X509Certificates.OpenFlags]"ReadWrite")
 $store.Add($newCert)
 return $newCertThumbprint
}

Write-Host Installing self-signed certificate Cert:\LocalMachine\My and Cert:\LocalMachine\Root ..

$certinstalledThumbprint = AddSelfSignedCertificateToSSL 'someacmeapp.somedomain.net'

Write-Host Added certificate $certinstalledThumbprint to Cert:\LocalMachine\My and Cert:\LocalMachine\Root and set this up as the SSL certificate on Default Web Site.




Thursday, 28 May 2020

Creating an AngularJs directive for a horizontal scroller at top and bottom of HTML container element

I made an AngularJs directive today that adds a horizontal scroller at top and bottom of an HTML container element, such as text area, table or div. The AngularJs directive uses the link function of AngularJs to prepend and wrap the necessary scrolling mechanism and add some Javascript scroll event handlers using jQuery.

import angular from 'angular';

var app = angular.module('plunker', []);
app.controller('MainCtrl', function($scope, $compile) {
  $scope.name = 'Dual wielded horizontal scroller';
});

app.directive('doubleHscroll', function($compile) {
  return {
    restrict: 'C',
    link: function(scope, elem, attr){

      var elemWidth = parseInt(elem[0].clientWidth);

      elem.wrap(`<div id='wrapscroll' style='width:${elemWidth}px;overflow:scroll'></div>`); 
      //note the top scroll contains an empty space as a 'trick' 
      $('#wrapscroll').before(`<div id='topscroll' style='height:20px; overflow:scroll;width:${elemWidth}px'><div style='min-width:${elemWidth}px'> </div></div>`);

      $(function(){
        $('#topscroll').scroll(function(){
          $("#wrapscroll").scrollLeft($("#topscroll").scrollLeft());
        });
        $('#wrapscroll').scroll(function() {
          $("#topscroll").scrollLeft($("#wrapscroll").scrollLeft());
        });

      });  

    }

  };


});


The HTML that uses this directive, restricted to 'C' (class) is then simply using the class 'double-Hscroll' following AngularJs 'snake escaping' naming convention of capitalization and dashes.

<!DOCTYPE html>

<html>
  <head>
    <link rel="stylesheet" href="lib/style.css" />
    <script src="lib/script.js"></script>
    <script
  src="https://code.jquery.com/jquery-3.5.1.js"
  integrity="sha256-QWo7LDvxbWT2tbbQ97B53yJnYU3WhH/C8ycbRAkjPDc="
  crossorigin="anonymous"></script>
  </head>

  <body ng-app="plunker" ng-cloak>
    <div ng-controller="MainCtrl">
      <h1>Hello {{name}}</h1>
      <p>Dual horizontal scroll top and below a text area.</p>
      <textarea noresize class="double-hscroll" rows="10" cols="30">
        lorem ipsum dolores  lorem ipsum dolores
      lorem ipsum dolores
      lorem ipsum dolores sit amen
      lorem ipsum dolores
      lorem ipsum dolores sit amen
      lorem ipsum dolores
      lorem ipsum dolores amen sit
     
      </textarea>
    </div>
  </body>
</html>

Tuesday, 7 April 2020

Writing to Event Log in .Net Core (Tested with .Net Core 3.1)

Writing to the Event Log in .Net Core requires first a Nuget package installation
Install-Package Microsoft.Extensions.Logging.EventLog -Version 3.1.2
Note that the correct version to install depends on the version of .Net Core you are running.The package above was tested OK with .Net Core. Then we need to add EventLog. In the Program class we can do this like so:
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Logging.EventLog;

namespace SomeAcme.SomeApi
{
    public class Program
    {
        public static void Main(string[] args)
        {
            CreateHostBuilder(args).Build().Run();
        }

        public static IHostBuilder CreateHostBuilder(string[] args) =>
            Host.CreateDefaultBuilder(args)
                .ConfigureLogging((hostingContext, logging) =>
                {
                    logging.ClearProviders();
                    logging.AddConfiguration(hostingContext.Configuration.GetSection("Logging"));
                    logging.AddEventLog(new EventLogSettings()
                    {
                        **SourceName = "SomeApi",
                        LogName = "SomeApi",**
                        Filter = (x, y) => y >= LogLevel.Warning
                    });
                    logging.AddConsole();
                })
                .ConfigureWebHostDefaults(webBuilder =>
                {
                    webBuilder.UseStartup();
                });
    }
}
And our appsettings.json file includes setup:
{
  "ConnectionStrings": {
    "DefaultConnection": "Server=.\\SQLEXPRESS;Database=SomeApi;Trusted_Connection=True;MultipleActiveResultSets=true"
  },
  **"Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft": "Warning",
      "Microsoft.Hosting.Lifetime": "Information"
    }
  },**
  "AllowedHosts": "*"
}
We can inject the ILogger instance
using SomeAcme.SomeApi.SomeModels;
using SomeAcme.SomeApi.Services;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
using System.Collections.Generic;

namespace SomeAcme.SomeApi.Controllers
{
    [Route("api/[controller]")]
    [ApiController]
    public class SomeController : ControllerBase
    {
        private readonly ISomeService _healthUnitService;
        private readonly ILogger _logger;

        public SomeController(ISomeService someService, ILogger logger)
        {
            _someService= someService;
            _logger = logger;
        }
        // GET: api/Some
        [HttpGet]
        public IEnumerable GetAll()
        {
            return _someService.GetAll();
        }
    }
}

More advanced use, add a global exception handler inside Configure method of Startup class in .Net Core:
        //Set up a global error handler for handling Unhandled exceptions in the API by logging it and giving a HTTP 500 Error with diagnostic information in Development and Staging
        app.UseExceptionHandler(errorApp =>
        {
            errorApp.Run(async context =>
            {
                context.Response.StatusCode = 500; // or another Status accordingly to Exception Type
                context.Response.ContentType = "application/json";

                var status = context.Features.Get();

                var error = context.Features.Get();
                if (error != null)
                {
                    var ex = error.Error;
                    string exTitle = "Http 500 Internal Server Error in SomeAcme.SomeApi occured. The unhandled error is: ";
                    string exceptionString = !env.IsProduction() ? (new ExceptionModel
                    {
                        Message = exTitle + ex.Message,
                        InnerException = ex?.InnerException?.Message,
                        StackTrace = ex?.StackTrace,
                        OccuredAt = DateTime.Now,
                        QueryStringOfException = status?.OriginalQueryString,
                        RouteOfException = status?.OriginalPath
                    }).ToString() : new ExceptionModel()
                    {
                        Message = exTitle + ex.Message,
                        OccuredAt = DateTime.Now
                    }.ToString();
                    try
                    {
                        _logger.LogError(exceptionString);
                    }
                    catch (Exception err)
                    {
                        Console.WriteLine(err);
                    }
                    await context.Response.WriteAsync(exceptionString, Encoding.UTF8);
                }
            });
        });

And finally a helper model to pack our exception information into.

using System;
using Newtonsoft.Json;

namespace SomeAcme.SomeApi.Models
{
    /// 
    /// Exception model for generic useful information to be returned to client caller
    /// 
    public class ExceptionModel
    {
        public string Message { get; set; }
        public string InnerException { get; set; }
        public DateTime OccuredAt { get; set; }
        public string StackTrace { get; set; }
        public string RouteOfException { get; set; }
        public string QueryStringOfException { get; set; }

        public override string ToString()
        {
            return JsonConvert.SerializeObject(this);
        }
    }
}

The tricky bit here is to get hold of a logger inside the Startup class. You can inject ILoggerFactory for this and just do :

_logger = loggerFactory.CreateLogger();

Where _logger is used in the global error handler above. Now back again to the question of how to write to the event log, look at the source code for SomeController above. We inject ILogger here. Just use that instance and it offers different methods for writing to your configured logs. Since we added in the Program class event log, this happens automatically. Before you test out the code above, run the following Powershell script as administrator to get your event log source:
New-EventLog -LogName SomeApi -SourceName SomeApi
What I like with this approach is that if we do everything correct, the exceptions pops up inside the SomeApi source nicely and not inside the application event log (clutter IMHO).

Sunday, 5 April 2020

Deploying an SQL Express database in Azure Devops pipeline with YAML and generating and updating the database with migrate scripts using EF Core Code First tools

Here a full example of how I achieved running Integration tests using Sql Express in Azure Devops. I had to use the YAML based pipelines so I could use simonauner's approach using Chocolatey to install Sql Express. Make note that I had to install EF Core tools since I use .Net Core 3.1 in this pipeline. Also note that I generate an EF Code First migration SQL file on the fly so that the rigged SQL Express instance is filled with contents. Deploy SQL Express instance in Azure Devops, install and generate and run EF Code first migration sql script to update database with schema and seed data using EF Code First tools.

# ASP.NET Core (.NET Framework)
# Build and test ASP.NET Core projects targeting the full .NET Framework.
# Add steps that publish symbols, save build artifacts, and more:
# https://docs.microsoft.com/azure/devops/pipelines/languages/dotnet-core

trigger:
- feature/testability

pool:
  vmImage: 'windows-latest'

variables:
  solution: '**/*.sln'
  buildPlatform: 'Any CPU'
  buildConfiguration: 'Release'

steps:
- script: choco install sql-server-express
- task: NuGetToolInstaller@1

- task: VisualStudioTestPlatformInstaller@1
  displayName: 'Visual Studio Test Platform Installer'
  inputs:
    versionSelector: latestStable

- task: NuGetCommand@2
  inputs:
    restoreSolution: '$(solution)'

- task: DotNetCoreCLI@2
  displayName: Build
  inputs:
    command: build
    projects: '**/*.csproj'
    arguments: '--configuration Debug' # Update this to match your need

- script: 'dotnet tool install --global dotnet-ef'
  displayName: 'Generate EF Code First Migrations SQL Script Update script'

- script: 'dotnet ef migrations script -i -o %BUILD_ARTIFACTSTAGINGDIRECTORY%\migrate.sql --project .\SomeAcme\SomeAcme.csproj'
  displayName: 'Generate EF Code First Migrations migrate.sql'

- script: 'sqlcmd -S .\SQLEXPRESS -Q "CREATE DATABASE [SomeAcmeDb]"'
  displayName: 'Create database SomeAcmeDb in Azure Devops SQL EXPRESS'

- script: 'sqlcmd -i %BUILD_ARTIFACTSTAGINGDIRECTORY%\migrate.sql -S .\SQLEXPRESS -d SomeAcmeDb'
  displayName: ' Run migrate.sql on SQL EXPRESS in Azure Devops'

# PowerShell
# Run a PowerShell script on Linux, macOS, or Windows
- task: PowerShell@2
  inputs:
    targetType: 'inline' # Optional. Options: filePath, inline
    #filePath: # Required when targetType == FilePath
    #arguments: # Optional
    script: 'gci -recurse -filter *.dll' # Required when targetType == Inline
    #errorActionPreference: 'stop' # Optional. Options: stop, continue, silentlyContinue
    #failOnStderr: false # Optional
    #ignoreLASTEXITCODE: false # Optional
    #pwsh: false # Optional
    #workingDirectory: # Optional

- task: VSTest@2
  displayName: 'VsTest - testAssemblies'
  inputs:
    testAssemblyVer2: |
     **\*SomeAcme.Tests.dll
     !**\*TestAdapter.dll
     !**\obj\**
    vsTestVersion: toolsInstaller
    testFiltercriteria: 'Category=IntegrationTest'
    runInParallel: false
    codeCoverageEnabled: false
    testRunTitle: 'XUnit tests SomeAcme solution integration test starting'
    failOnMinTestsNotRun: true
    rerunFailedTests: false

Mocking HttpClient in .Net core 3 with Moq

I worked with HttpClient today and needed to write some unit tests. Here is how I did it. First off, we need to define an HttpClientFactory interface like this:
    public interface IHttpClientFactory
    {
        HttpClient CreateHttpClient();
    }
Your API code must then not directly create an http client, but pass in a IHttpClientFactory instance, allowing for tailored functionality such as mocking / unit testing. A default implementation could be:
  public class DefaultHttpClientFactory : IHttpClientFactory
        {
            public HttpClient CreateHttpClient()
            {
                return new HttpClient();
            }
        }
And a mock implementation using Moq then looks like this:

using Moq;
using Moq.Protected;
using System.Net;
using System.Net.Http;
using System.Threading;
using System.Threading.Tasks;

namespace SomeAcme.SomeApi.Test
{
    public class MockHttpClientFactory : IHttpClientFactory
    {
        private HttpResponseMessage _httpContentMessage;

        public HttpClient CreateHttpClient()
        {
            return new HttpClient(CreateMockedHttpMessageHandler());
        }

        private HttpMessageHandler CreateMockedHttpMessageHandler()
        {
            var handlerMock = new Mock<HttpMessageHandler>(MockBehavior.Strict);
            handlerMock
                .Protected()
                // Setup the PROTECTED method to mock
                .Setup<Task<HttpResponseMessage>>(
                    "SendAsync",
                    ItExpr.IsAny<HttpRequestMessage>(),
                    ItExpr.IsAny<CancellationToken>()
                )
                // prepare the expected response of the mocked http call
                .ReturnsAsync(SetupHttpResponseMessage())
                .Verifiable();

            handlerMock
                .Protected()
                // Setup the PROTECTED method to mock
                .Setup(
                    "Dispose",
                    ItExpr.IsAny<bool>()
                )
                // prepare the expected response of the mocked http call
                .Verifiable();
            return handlerMock.Object;
        }

        /// <summary>
        /// Set up the desired http response of unit tests
        /// </summary>
        /// <param name="statusCode"></param>
        /// <param name="responseJson"></param>
        public void SetHttpResponseMessage(HttpStatusCode statusCode, string responseJson)
        {
            _httpContentMessage = new HttpResponseMessage
            {
                StatusCode = statusCode,
                Content = new StringContent(responseJson)

            };

        }

        private HttpResponseMessage SetupHttpResponseMessage()
        {
            if (_httpContentMessage != null)
                return _httpContentMessage;
            return new HttpResponseMessage()
            {
                StatusCode = HttpStatusCode.OK,
                Content = new StringContent("[{'id':1,'value':'1'}]")
            }; //return default dummy implementation for easy green testing of HttpClient..
        }
    }
}
The key is to implement a mocked HttpMessageHandler which is then injected into the real HttpClient class. And also expose a method SetupHttpResponseMessage() allowing unit tests to specify desired http status code and json payload in the response. This is a very basic approach of unit testing HttpClient, so you can get code coverage of your HttpClient and related code in the application layer where your use it. Make sure you now inject the MockHttpClientFactory into your code and initialize it in your testse setting the SetupHttpResponseMessage. Tests should go a green again despite you actually use the HttpClient (with a mocked HttpMessageHandler) !

Friday, 3 April 2020

User friendly and Flexible numeric textbox for decimal numbers in WPF

Adapting WPF to allow a numeric textbox in WPF sounds very trivial, but it is not! A user friendly textbox in WPF couldhave different aspects. It could be possible to: - Only allow numbers or decimal separator - Possible to specify number of digits for integer part and number of digits for decimal part - Specify an empty default value - Still rely on default components such as WPF Textbox The following WPF Converter allows to restrict user input using ConvertBack method. Usually a developer implements the Convert method to transform output, here we use ConvertBack to filter input to only allow numbers or decimal separator.

NumericFormatConverter


using Hemit.OpPlan.Common;
using System;
using System.Globalization;
using System.Linq;
using System.Threading;
using System.Windows.Data;
namespace Hemit.OpPlan.Client.Infrastructure.Converters
{
    public class NumericFormatConverter : IValueConverter
    {
        public int IntegerLength { get; set; }
        public int DecimalLength { get; set; }
        public string DefaultValue { get; set; }
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            return value;       
        }
        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            if (value == null)
                return DefaultValue;
            string adjustedValue = AdjustValueToAcceptingFormat(value.ToString());
            return adjustedValue;
        }
        private string AdjustValueToAcceptingFormat(string value)
        {
            if (string.IsNullOrEmpty(value))
                return DefaultValue;
            char decimalSeparator = Thread.CurrentThread?.CurrentCulture?.NumberFormat?.NumberDecimalSeparator.ToCharArray().First() ?? ',';
            string[] compounds = value.Split(new[] { decimalSeparator });
            if (compounds.Length <= 0)
            {
                return DefaultValue; //default to zero
            }
            if (compounds.Length == 1)
            {
                return NumericDigits(compounds[0], decimalSeparator);
            }
            return $"{NumericDigits(compounds[0], decimalSeparator).Truncate(3)}{decimalSeparator}{NumericDigits(compounds[1], decimalSeparator).Truncate(1)}";
        }
        private static string NumericDigits(string input, char decimalSeparator)
        {
            return string.Join("", input.ToCharArray().Where(ch => Char.IsDigit(ch) || ch == decimalSeparator)).Truncate(3);
        }
    }
}

If you rely on MVVM, you can bind up a numeric value with a proxy property with datatype string for flexible input.

   [State]
   [NotifyPropertyChanged(true)]
   [AffectsOtherProperty("BodyMassIndex")]
   [Range(0.0, 500, ErrorMessage = @"Max Weight is surpassed")]
   public double? Weight { get; set; }

   private string _weightInputValue;

   public string WeightInputValue
   {
       get { return _weightInputValue; }
       set
       {
           if (_weightInputValue != value)
           {
               _weightInputValue = value;
               double weight;
               if (double.TryParse(_weightInputValue, out weight))
               {
                   Weight = weight;
               }
               RaisePropertyChanged(() => WeightInputValue);
           }
       }
   }

Never mind the Postsharp aspects for State, NotifyPropertyChanged and AffectsOtherProperty listed here, they are not necessary in your use case. But shows a real world scenario. In WPF frontend you can then bind up the WPF converter like this:

      <TextBlock Grid.Row="7" Grid.Column="2" Margin="2" Text="Vekt (kg)" VerticalAlignment="Center" HorizontalAlignment="Left" />
                            <TextBox Grid.Row="7" Grid.Column="4" MaxLength="5" Height="24" behaviors:TextBoxRegExBehavior.RegularExpressionProperty="^\d+[,|.]*\d*$" FontWeight="Normal"
                             HorizontalAlignment="Left"
                             behaviors:TextBoxRegExBehavior.MaxLength="5" behaviors:TextBoxRegExBehavior.MustParseToType="{x:Type sys:Double}" behaviors:TextBoxRegExBehavior.EmptyValue="0" 
                             Margin="2,2,2,2" Width="40" Text="{Binding WeightInputValue, Converter={StaticResource numericFormatConverter}, ConverterCulture={x:Static gl:CultureInfo.CurrentCulture}, UpdateSourceTrigger=PropertyChanged, ValidatesOnExceptions=true}" 
                             Style="{StaticResource ReadOnlyTextBoxStyleHidingZero}" IsReadOnly="{Binding IsEditMode, Converter={StaticResource invertedBoolConverter}}" TabIndex="35" />

Again, much custom stuff here, but the key thing to notice is that you only need to make sure you bind against the proxy property of type string, the WPF converter numericFormatConverter handles the formatting of the input.
   <converters:NumericFormatConverter x:Key="numericFormatConverter" IntegerLength="3" DecimalLength="1" DefaultValue=""></converters:NumericFormatConverter>

Friday, 28 February 2020

Strongly typed ConfigurationManager in .NET Framework

Handling configuration files in .NET Framework is often tedious. You retrieve the app setting as a string and must then parse it out. Dont you wish we could have a generic method to get a strongly typed app setting instead and spare ourselves with some code ? Sure you can!

using System;
using System.ComponentModel;
using System.Configuration;

namespace Hemit.OpPlan.Common.Extensions
{

    /// <summary>
    /// Utility methods for ConfigurationManager. Also included methods for handling OpenExeConfiguration (running process configuration, for example in tests and installers)
    /// </summary>
    public static class ConfigurationManagerWrapper
    {
        /// <summary>
        /// Sets an appsetting for the exe configuration
        /// </summary>
        /// <param name="appsetting"></param>
        /// <param name="value"></param>
        public static void SetAppsettingForExecConfiguration(string appsetting, object value)
        {
            System.Configuration.Configuration config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
            config.AppSettings.Settings[appsetting].Value = Convert.ToString(value);
            config.Save(ConfigurationSaveMode.Modified);
        }

        /// <summary>
        /// Sets an appsetting for the exe configuration
        /// </summary>
        /// <param name="appsetting"></param>
        /// <param name="value"></param>
        public static string GetAppsettingExecConfiguration(string appsetting, object value)
        {
            return ConfigurationManager.AppSettings[appsetting];
        }

        /// <summary>
        /// Sets an appsetting for the exe configuration
        /// </summary>
        /// <param name="appsetting"></param>
        /// <param name="value"></param>
        public static void SetAppsettingForConfiguration(string appsetting, object value)
        {
            ConfigurationManager.AppSettings[appsetting] = Convert.ToString(value);
        }

        /// <summary>
        /// Sets an appsetting for the exe configuration
        /// </summary>
        /// <param name="appsetting"></param>
        /// <param name="value"></param>
        public static string GetAppsettingForExecConfiguration(string appsetting, object value)
        {
            System.Configuration.Configuration config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
            return config.AppSettings.Settings[appsetting].Value;
        }


        /// <summary>
        /// Use this extension method to get a strongly typed app setting from the configuration file.
        /// Returns app setting in configuration file if key found and tries to convert the value to a specified type. In case this fails, the fallback value
        /// or if NOT specified - default value - of the app setting is returned
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="appsettingKey"></param>
        /// <param name="fallback"></param>
        /// <returns></returns>
        public static T GetAppsetting<T>(string appsettingKey, T fallback = default(T))
        {
            string val = ConfigurationManager.AppSettings[appsettingKey] ?? "";
            if (!string.IsNullOrEmpty(val))
            {
                try
                {
                    Type typeDefault = typeof(T);
                    var converter = TypeDescriptor.GetConverter(typeof(T));
                    return converter.CanConvertFrom(typeof(string)) ? (T)converter.ConvertFrom(val) : fallback;
                }
                catch (Exception err)
                {
                    Console.WriteLine(err); //Swallow exception
                    return fallback;
                }
            }
            return fallback;
        }

    }
}



Thursday, 20 February 2020

Generic method ShouldAll for FluentAssertions

This is a simple etension method for Fluent Assertions called ShouldAll that can be run on a collection and you can pass in your predicate of your choice and see the output. Consider this unit test:


         var oneyearPeriodComparions = new []
            {
                new ReferencePeriodComparisonResult { ReferencePeriod = reportPeriod2017 , CalculatedPeriod = calculatedReportPeriod2017.First() },
                new ReferencePeriodComparisonResult { ReferencePeriod = reportPeriod2017 , CalculatedPeriod = calculatedReportPeriod2017.Last()},
                new ReferencePeriodComparisonResult { ReferencePeriod = reportPeriod2018 , CalculatedPeriod = calculatedReportPeriod2018.First()},
                new ReferencePeriodComparisonResult { ReferencePeriod = reportPeriod2018 , CalculatedPeriod = calculatedReportPeriod2018.Last() },
                new ReferencePeriodComparisonResult { ReferencePeriod = reportPeriod2019 , CalculatedPeriod = calculatedReportPeriod2019.First() },
                new ReferencePeriodComparisonResult { ReferencePeriod = reportPeriod2019 , CalculatedPeriod = calculatedReportPeriod2019.Last() }
            };

            oneyearPeriodComparions.ShouldAll(comparison => comparison.CalculatedPeriod.ReportPeriodStartDateAndEndDateIsEqualTo(comparison.ReferencePeriod), outputPassingTests:true);


This uses this extension test for Fluent Assertions:

using FluentAssertions;
using System;
using System.Collections.Generic;
using System.Linq.Expressions;

namespace SomeAcme.SomeLib
{

    public static class FluentAssertionsExtensions
    {

        /// <summary>
        /// Inspects that all tests are passing for given collection and given predicate
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="instances"></param>
        /// <param name="predicate"></param>
        /// <param name="outputFailingTests"></param>
        public static void ShouldAll<T>(this IEnumerable<T> instances, Expression<Func<T, bool>> predicate, bool outputFailingTests = true, bool outputPassingTests = false)
        {
            foreach (var instance in instances)
            {
                var isTestPassing = predicate.Compile().Invoke(instance);
                if (!isTestPassing && outputFailingTests || outputPassingTests)
                    Console.WriteLine($@"Test Running against object: {instance} Test Pass?:{isTestPassing}");
                isTestPassing.Should().Be(true);
            }
        }
    }

}


Saturday, 4 January 2020

Implementing GetPropertyNames in Typescript

I am currently working on a Linq-like library for Typescript and wanted to implement something like GetProperties of C# in Typescript / Javascript. The more I work with Typescript and generics, the clearer picture I get of that you usually have to have an instantiated object with intialized properties to get any useful information out at runtime about properties of a class. But it would be nice to retrieve information anyways just from the constructor function object, or an array of objects and be flexible about this. I was following a question thread on Stack Overflow and found a good answer that helped me out: https://stackoverflow.com/questions/40636292/get-properties-of-a-class/59586570#59586570 Here is what I ended up with for now. First off, I define Array prototype method ('extension method' for you C# developers).

export { } //creating a module of below code
declare global {
  interface Array>T< {
    GetProperties>T<(TClass: Function, sortProps: boolean): string[];
} }
The GetProperties method then looks like this, inspired by madreasons answer.

if (!Array.prototype.GetProperties) {
  Array.prototype.GetProperties = function >T<(TClass: any = null, sortProps: boolean = false): string[] {
    if (TClass === null || TClass === undefined) {
      if (this === null || this === undefined || this.length === 0) {
        return []; //not possible to find out more information - return empty array
      }
    }
    // debugger
    if (TClass !== null && TClass !== undefined) {
      if (this !== null && this !== undefined) {
        if (this.length < 0) {
          let knownProps: string[] = Describer.describe(this[0]).Where(x =< x !== null && x !== undefined);
          if (sortProps && knownProps !== null && knownProps !== undefined) {
            knownProps = knownProps.OrderBy(p =< p);
          }
          return knownProps;
        }
        if (TClass !== null && TClass !== undefined) {
          let knownProps: string[] = Describer.describe(TClass).Where(x =< x !== null && x !== undefined);
          if (sortProps && knownProps !== null && knownProps !== undefined) {
            knownProps = knownProps.OrderBy(p =< p);
          }
          return knownProps;
        }
      }
    }
    return []; //give up..
  }
}

The describer method is about the same as madreason's answer on Stack Overflow concerning this. It can handle both class Function and if you get an object instead. It will then use Object.getOwnPropertyNames if no class Function is given (i.e. the class 'type' for C# developers).

class Describer {
  private static FRegEx = new RegExp(/(?:this\.)(.+?(?= ))/g);
  static describe(val: any, parent = false): string[] {
    let isFunction = Object.prototype.toString.call(val) == '[object Function]';
    if (isFunction) {
      let result = [];
      if (parent) {
        var proto = Object.getPrototypeOf(val.prototype);
        if (proto) {
          result = result.concat(this.describe(proto.constructor, parent));
        }
      }
      result = result.concat(val.toString().match(this.FRegEx));
      result = result.Where(r =< r !== null && r !== undefined);
      return result;
    }
    else {
      if (typeof val == "object") {
        let knownProps: string[] = Object.getOwnPropertyNames(val);
        return knownProps;
      }
    }
    return val !== null ? [val.tostring()] : [];
  }
}

Here you see two specs for testing this out with Jasmine.

class Hero {
  name: string;
  gender: string;
  age: number;
  constructor(name: string = "", gender: string = "", age: number = 0) {
    this.name = name;
    this.gender = gender;
    this.age = age;
  }
}

class HeroWithAbility extends Hero {
  ability: string;
  constructor(ability: string = "") {
    super();
    this.ability = ability;
  }
}

describe('Array Extensions tests for TsExtensions Linq esque library', () =< {

  it('can retrieve props for a class items of an array', () =< {
    let heroes: Hero[] = [>Hero<{ name: "Han Solo", age: 44, gender: "M" }, >Hero<{ name: "Leia", age: 29, gender: "F" }, >Hero<{ name: "Luke", age: 24, gender: "M" }, >Hero<{ name: "Lando", age: 47, gender: "M" }];
    let foundProps = heroes.GetProperties(Hero, false);
    //debugger
    let expectedArrayOfProps = ["name", "age", "gender"];
    expect(foundProps).toEqual(expectedArrayOfProps);
    expect(heroes.GetProperties(Hero, true)).toEqual(["age", "gender", "name"]);
  });

  it('can retrieve props for a class only knowing its function', () =< {
    let heroes: Hero[] = [];
    let foundProps = heroes.GetProperties(Hero, false);
    let expectedArrayOfProps = ["this.name", "this.gender", "this.age"];
    expect(foundProps).toEqual(expectedArrayOfProps);
    let foundPropsThroughClassFunction = heroes.GetProperties(Hero, true);
    //debugger
    expect(foundPropsThroughClassFunction.SequenceEqual(["this.age", "this.gender", "this.name"])).toBe(true);
  });

..

And as madreason mentioned, you have to initialize the props to get any information out from just the class Function itself, or else it is stripped away when Typescript code is turned into Javascript code. Typescript 3.7 is very good with Generics, but coming from a C# and Reflection background, some fundamental parts of Typescript and generics still feels somewhat loose and unfinished business. Like my code here, but at least I got out the information I wanted - a list of property names for a given class or instance of objects.

Tuesday, 31 December 2019

Aggregate in Typescript

I have implemented Aggregate method in my Linq library written for Typescript.

if (!Array.prototype.Aggregate) {
  Array.prototype.Aggregate = function <T>(accumulator: any, currentValue: any, reducerFunc: (accumulator: any, currentValue: any) => any): any {
    //debugger
    if (reducerFunc === undefined || reducerFunc === null) {
      reducerFunc = (accumulator, currentValue) => accumulator + currentValue;
    }
    let result = this.reduce(reducerFunc);
    return result;
  }
}

if (!Array.prototype.AggregateSelect) {
  Array.prototype.AggregateSelect = function <T>(property: (keyof T), accumulator: any, currentValue: any, reducerFunc: (accumulator: any, currentValue: any) => any): any {
    //debugger
    if (reducerFunc === undefined || reducerFunc === null) {
      reducerFunc = (accumulator, currentValue) => accumulator + currentValue;
    }
    //debugger
    let result = this.Select(property).map(n => n[property]).reduce(reducerFunc);
    return result;
  }
}

Here are some Jasmine tests for these two methods - note that I also support setting the initial value.
  it('can aggregate items to expected result using Aggregate on array of items of numbers', () => {
    let someNums = [1, 2, 3, 4];
    let result = someNums.Aggregate(0, 0, null);
    expect(result).toBe(10);
  });

  it('can aggregate items and project to expected result using AggregateSelect on array of items of objects', () => {
    let someArray: any[] = [];
    someArray.push(<SomeClass>{ Name: "Foo", Num: 1 });
    someArray.push(<SomeClass>{ Name: "FooBaz", Num: 4 });
    someArray.push(<SomeClass>{ Name: "AllyoBaze", Num: 7 });
    let result = someArray.AggregateSelect<SomeClass>("Num", 0, 0, null);
    expect(result).toBe(12);
  });

  it('can aggregate once more items and project to expected result using AggregateSelect on array of items of objects with accumulator value set initially', () => {
    let someArray: Student[] = [];
    someArray.push(<Student>{ StudentID: 1, StudentName: "John", Age: 13 });
    someArray.push(<Student>{ StudentID: 2, StudentName: "Moin", Age: 21 });
    someArray.push(<Student>{ StudentID: 3, StudentName: "Bill", Age: 18 });
    someArray.push(<Student>{ StudentID: 4, StudentName: "Ram", Age: 20 });
    someArray.push(<Student>{ StudentID: 5, StudentName: "Ron", Age: 15 });
    let result = someArray.AggregateSelect<Student>("StudentName", "Student Names: ", 0, (a, b) => a + "," + b);
    expect(result).toBe("John,Moin,Bill,Ram,Ron");
  });

My interface definition is growing everytime for my Linq Library! Here is how it looks now:

export { } //creating a module of below code
declare global {
  type predicate<T> = (arg: T) => boolean;
  type sortingValue<T> = (arg: T) => any;
  interface Array<T> {
    FirstOrDefault<T>(condition: predicate<T>): T;
    LastOrDefault<T>(condition: predicate<T>): T;
    Where<T>(condition: predicate<T>): T[];
    Count<T>(): number;
    CountBy<T>(condition: predicate<T>): number;
    Select<T>(...properties: (keyof T)[]): any[];
    GroupBy<T>(groupFunc: (arg: T) => string): any[];
    EnumerableRange(start: number, count: number): number[];
    Any<T>(condition: predicate<T>): boolean;
    All<T>(condition: predicate<T>): boolean;
    MaxSelect<T>(property: (keyof T)): any;
    MinSelect<T>(property: (keyof T)): any;
    Average<T>(): number;
    AverageSelect<T>(property: (keyof T)): number;
    Max(): any;
    Min(): any;
    Sum(): any;
    Distinct<T>(): T[];
    DistinctBy<T>(property: (keyof T)): any;
    SumSelect<T>(property: (keyof T)): any;
    Intersect<T>(otherArray: T[]): T[];
    IntersectSelect<T>(property: (keyof T), otherArray: T[]): T[];
    MinSelect<T>(property: (keyof T)): any;
    OrderBy<T>(sortMember: sortingValue<T>): T[];
    OrderByDescending<T>(sortMember: sortingValue<T>): T[];
    ThenBy<T>(sortMember: sortingValue<T>): T[];
    OfType<T>(compareObject: T): T[];
    SequenceEqual<T>(compareArray: T): boolean;
    Take<T>(count: number): T[];
    TakeWhile<T>(condition: predicate<T>): T[];
    SkipWhile<T>(condition: predicate<T>): T[];
    Skip<T>(count: number): T[];
    defaultComparerSort<T>(x: T, y: T);
    ElementAt<T>(index: number);
    ElementAtOrDefault<T>(index: number);
    Aggregate<T>(accumulator: any, currentValue: any, reducerFunc: (accumulator: any, currentValue: any) => any): any;
    AggregateSelect<T>(property: (keyof T), accumulator: any, currentValue: any, reducerFunc: (accumulator: any, currentValue: any) => any): any;
  }
}

DistinctBy operator written in Typescript

I am extended my Linq library for Typescript with many more methods! Here is my implementation of DistinctBy.

if (!Array.prototype.DistinctBy) {
  Array.prototype.DistinctBy = function <T>(property: (keyof T)): T[] {
    if (this === null || this === undefined) {
      return [];
    }
    let filteringArray = this.Select(property).map(n => n[property]);

    let distinctRunOnArray = this.filter((value, index, array) => {
      let valueProperty = value[property];
      return filteringArray.indexOf(valueProperty) === index;
    });
    return distinctRunOnArray;
  }
}

This Jasmine test can test this operator out.
describe('TSLinq Jasmine tests', () => {

  it('can filter out duplicates using DistinctBy on array of items of objects', () => {
    let someArray: Student[] = [];
    someArray.push(<Student>{ StudentID: 1, StudentName: "John", Age: 13 });
    someArray.push(<Student>{ StudentID: 2, StudentName: "Moin", Age: 21 });
    someArray.push(<Student>{ StudentID: 2, StudentName: "Moin", Age: 21 });
    someArray.push(<Student>{ StudentID: 4, StudentName: "Ram", Age: 20 });
    someArray.push(<Student>{ StudentID: 5, StudentName: "Ron", Age: 15 });
    let expectedArray: Student[] = [];
    expectedArray.push(<Student>{ StudentID: 1, StudentName: "John", Age: 13 });
    expectedArray.push(<Student>{ StudentID: 2, StudentName: "Moin", Age: 21 });
    expectedArray.push(<Student>{ StudentID: 4, StudentName: "Ram", Age: 20 });
    expectedArray.push(<Student>{ StudentID: 5, StudentName: "Ron", Age: 15 });
    let result = someArray.DistinctBy<Student>("StudentID");
    expect(result).toEqual(expectedArray);
  });


});
The Student class is simple:

class Student {
  StudentID: number;
  StudentName: string;
  Age: number;
}

Implementing OfType in Typescript

I am working on my Linq library for Typescript and wanted to implement OfType. Turns out, this is hard because the generic type arguments in Typescript usually requires a value, i.e. an object instance of type T to get any shape information at run-time. So I ended up passing in a vanilla object setting default property values instead. Here is how my implementation ended up:

function isOfSimilarShape<T>(input: any, compareObject: T): boolean {
  if (input === undefined || input === null || compareObject === undefined || compareObject === null)
    return false;

  let propsOfInput = Object.keys(input);
  let propsOfCompareObject = Object.keys(compareObject);
  //debugger
  let sameShapeOfInputAndCompareObject = propsOfInput.EqualTo(propsOfCompareObject);
  return sameShapeOfInputAndCompareObject;
}

if (!Array.prototype.OfType) {
  Array.prototype.OfType = function <T>(compareObject: T): T[] {
    let result: T[] = [];
    this.forEach(el => {
      //debugger
      let t: T = null;
      if (isOfSimilarShape(el, compareObject))
        result.push(el);
    });
    return result;
  }
}

The following Jasmine test shows its usage:

describe('Array Extensions tests', () => {

  it('can find desired items using OfType of type T', () => {
    let someMixedArray: any[] = [];
    someMixedArray.push(<SomeClass>{ Name: "Foo", Num: 1 });
    someMixedArray.push(<SomeOtherClass>{ SomeName: "BarBazBaze", SomeOtherNum: 813 });
    someMixedArray.push(<SomeClass>{ Name: "FooBaz", Num: 4 });
    someMixedArray.push(<SomeOtherClass>{ SomeName: "BarBaze", SomeOtherNum: 13 });
    someMixedArray.push(<SomeClass>{ Name: "AllyoBaze", Num: 7 });

    let compareObject = <SomeClass>{ Name: "", Num: 0 };
    let filteredArrayBySpecifiedType = someMixedArray.OfType(compareObject);
    console.log(filteredArrayBySpecifiedType);

    expect(filteredArrayBySpecifiedType.All(item => <SomeClass>item !== undefined)).toBe(true, "Expected only items of type SomeOtherClass in the filtered array after running OfType of SomeOtherClass on it.");
  });

It would be nice if we did not have to pass in a vanilla object and populate its properties, but I could not find any tips online or in the Typescript documentation for how to implement extracting type information from generic arguments of Typescript. This is very easy in C#, but while Typescript gives compilation type information, getting runtime information from generic arguments in the Javascript code that Typescript compiles into turned much harder.

Monday, 30 December 2019

More methods: Any, All, EnumerableRange, GroupBy for Linq like library written in TypeScript

I am extending my TypeScript library written to target Linq like methods, which can be used with Angular 8 and Typescript also. You can find my Github repo SimpleLinqLibraryTs here: https://github.com/toreaurstadboss/SimpleLinqLibraryTs/blob/master/src/app/array-extensions.ts

export { } //creating a module of below code
declare global {
  type predicate<T> = (arg: T) => boolean;
  interface Array<T> {
    FirstOrDefault<T>(condition: predicate<T>): T;
    LastOrDefault<T>(condition: predicate<T>): T;
    Where<T>(condition: predicate<T>): T[];
    Select<T>(...properties: (keyof T)[]): any[];
    GroupBy<T>(groupFunc: (arg: T) => string): any[];
    EnumerableRange(start: number, count: number): number[];
    Any<T>(condition: predicate<T>): boolean;
    All<T>(condition: predicate<T>): boolean;
  }
}

if (!Array.prototype.FirstOrDefault) {
  Array.prototype.FirstOrDefault = function <T>(condition: predicate<T>): T {
    let matchingItems: T[] = this.filter((item: T) => {
      if (condition(item))
        return item;
    });
    return matchingItems.length > 0 ? matchingItems[0] : null;
  }
}

if (!Array.prototype.Any) {
  Array.prototype.Any = function <T>(condition: predicate<T>): boolean {
    if (this.length === 0)
      return false;
    let result: boolean = false;
    for (let index = 0; index < this.length; index++) {
      const element = this[index];
      if (condition(element)) {
        result = true;
        break;
      }
    }
    return result;
  }
}

if (!Array.prototype.All) {
  Array.prototype.All = function <T>(condition: predicate<T>): boolean {
    if (this.length === 0)
      return false;
    let result: boolean = true;
    for (let index = 0; index < this.length; index++) {
      const element = this[index];
      if (!condition(element)) {
        result = false;
      }
    }
    return result;
  }
}

if (!Array.prototype.LastOrDefault) {
  Array.prototype.LastOrDefault = function <T>(condition: predicate<T>): T {
    let matchingItems: T[] = this.filter((item: T) => {
      if (condition(item))
        return item;
    });
    return matchingItems.length > 0 ? matchingItems[matchingItems.length - 1] : null;
  }
}

if (!Array.prototype.Select) {
  Array.prototype.Select = function <T>(...properties: (keyof T)[]): any[] {
    let result = [];
    for (let i = 0; i < this.length; i++) {
      let item: any = {};
      for (let j = 0; j < properties.length; j++) {
        let key = properties[j];
        item[key] = this[i][properties[j]];
      }
      result.push(item);
    }
    return result;
  }
}

if (!Array.prototype.GroupBy) {
  Array.prototype.GroupBy = function <T>(groupFunc: (arg: T) => string): any[] {
    let groups: any = {};
    this.forEach(el => {
      let itemKeyValue: any = groupFunc(el);
      if (itemKeyValue in groups === false) {
        groups[itemKeyValue] = [];
      }
      groups[itemKeyValue].push(el);
    });
    let result = Object.keys(groups).map(key => {
      return {
        key: key,
        values: groups[key]
      }
    });
    return result;
  }
}

function* Range(start, count) {
  for (let x = start; x < start + count; x++) {
    yield x;
  }
}

if (!Array.prototype.EnumerableRange) {
  Array.prototype.EnumerableRange = function (start: number, count: number): number[] {
    let generatedRange = [...Range(start, count)];
    return generatedRange;
  }
}


if (!Array.prototype.Where) {
  Array.prototype.Where = function <T>(condition: predicate<T>): T[] {

    let matchingItems: T[] = this.filter((item: T) => {

      if (condition(item)) {
        return true;
      }
    });
    return matchingItems;
  }
}



Friday, 27 December 2019

Implementing Linq methods on arrays with Typescript for Angular 8

This article will look into implementing Linq methods on array with Typescript for Angular 8. First off, I have created a repo for this article on Github. Simple Linq Library written with Typescript for Angular 8 This only implements FirstOrDefault and Where Linq operators on arrays. We first need to define our Array prototype methods. Since we use Angular, first we define an empty module using export {} and then declare global { .. } Inside our declare global we define our type predicate and our methods Where and FirstOrDefault. Then we define our two methods if they do not exist yet on Array.prototype. The special syntax above is adaptions for Typescript and Angular. I have tested this with Angular 8. Here is the Typescript code I ended up with:

export { } //creating a module of below code
declare global {
  type predicate<T> = (arg: T) => boolean;
  interface Array<T> {
    FirstOrDefault<T>(condition: predicate<T>): T;
    Where<T>(condition: predicate<T>): T[];
  }
}

if (!Array.prototype.FirstOrDefault) {
  Array.prototype.FirstOrDefault = function <T>(condition: predicate<T>): T {
    let matchingItems: T[] = this.filter((item: T) => {

      if (condition(item)) {
        return item;
      }
    });
    if (matchingItems.length > 0) {
      return matchingItems[0];
    }
    return null;
  }
}

if (!Array.prototype.Where) {
  Array.prototype.Where = function <T>(condition: predicate<T>): T[] {

    let matchingItems: T[] = this.filter((item: T) => {

      if (condition(item)) {
        return true;
      }
    });
    return matchingItems;
  }
}

Let us define some input data - an array to work on and pass into predicates where we can test out FirstOrDefault and Where methods !

import { Movie } from './movie';

export const StarWarsMovies : Array>Movie< =
 [{
      "title" : "Star Wars: Episode I - The Phantom Menace",
      "episode_number" : "1",
      "main_characters" : ["Qui-Gon Jinn", "Obi-Wan Kenobi", "Anakin Skywalker", "Padmé Amidala", "Jar Jar Binks", "Darth Maul"],
      "description" : "The evil Trade Federation, led by Nute Gunray is planning to take over the peaceful world of Naboo. Jedi Knights Qui-Gon Jinn and Obi-Wan Kenobi are sent to confront the leaders. But not everything goes to plan. The two Jedi escape, and along with their new Gungan friend, Jar Jar Binks head to Naboo to warn Queen Amidala, but droids have already started to capture Naboo and the Queen is not safe there. Eventually, they land on Tatooine, where they become friends with a young boy known as Anakin Skywalker. Qui-Gon is curious about the boy, and sees a bright future for him. The group must now find a way of getting to Coruscant and to finally solve this trade dispute, but there is someone else hiding in the shadows. Are the Sith really extinct? Is the Queen really who she says she is? And what's so special about this young boy?",
      "poster" : "star_wars_episode_1_poster.png",
      "hero_image" : "star_wars_episode_1_hero.jpg"
    },

    {
      "title" : "Star Wars: Episode II - Attack of the Clones",
      "episode_number" : "2",
      "main_characters" : ["Obi-Wan Kenobi", "Anakin Skywalker", "Count Dooku", "Padmé Amidala", "Mace Windu", "Yoda", "Jango Fett", "Supreme Chancellor Palpatine"],
      "description" : "Ten years after the 'Phantom Menace' threatened the planet Naboo, Padmé Amidala is now a Senator representing her homeworld. A faction of political separatists, led by Count Dooku, attempts to assassinate her. There are not enough Jedi to defend the Republic against the threat, so Chancellor Palpatine enlists the aid of Jango Fett, who promises that his army of clones will handle the situation. Meanwhile, Obi-Wan Kenobi continues to train the young Jedi Anakin Skywalker, who fears that the Jedi code will forbid his growing romance with Amidala.",
      "poster" : "star_wars_episode_2_poster.png",
      "hero_image" : "star_wars_episode_2_hero.jpg"
    },

    {
      "title" : "Star Wars: Episode III - Revenge of the Sith",
      "episode_number" : "3",
      "main_characters" : ["Obi-Wan Kenobi", "Anakin Skywalker", "Count Dooku", "Padmé Amidala", "Mace Windu", "Yoda", "C-3PO", "Supreme Chancellor Palpatine"],
      "description" : "Three years after the onset of the Clone Wars; the noble Jedi Knights are spread out across the galaxy leading a massive clone army in the war against the Separatists. After Chancellor Palpatine is kidnapped, Jedi Master Obi-Wan Kenobi and his former Padawan, Anakin Skywalker, are dispatched to eliminate the evil General Grievous. Meanwhile, Anakin's friendship with the Chancellor arouses suspicion in the Jedi Order, and dangerous to the Jedi Knight himself. When the sinister Sith Lord, Darth Sidious, unveils a plot to take over the galaxy, the fate of Anakin, the Jedi order, and the entire galaxy is at stake. Upon his return, Anakin Skywalker's wife Padme Amidala is pregnant, but he is having visions of her dying in childbirth. Anakin Skywalker ultimately turns his back on the Jedi, thus completing his journey to the dark side and his transformation into Darth Vader. Obi-Wan Kenobi must face his former apprentice in a ferocious lightsaber duel on the fiery world of Mustafar.",
      "poster" : "star_wars_episode_3_poster.png",
      "hero_image" : "star_wars_episode_3_hero.jpg"
    },

    {
      "title" : "Star Wars: Episode IV - A New Hope",
      "episode_number" : "4",
      "main_characters" : ["Luke Skywalker", "Han Solo", "Princess Leia Organa", "Ben Kenobi", "Darth Vader", "C-3P0", "R2-D2", "Chewbacca"],
      "description" : "Part IV in George Lucas' epic, Star Wars: A New Hope opens with a Rebel ship being boarded by the tyrannical Darth Vader. The plot then follows the life of a simple farm boy, Luke Skywalker, as he and his newly met allies (Han Solo, Chewbacca, Obi-Wan Kenobi, C-3PO, R2-D2) attempt to rescue a Rebel leader, Princess Leia, from the clutches of the Empire. The conclusion is culminated as the Rebels, including Skywalker and flying ace Wedge Antilles make an attack on the Empire's most powerful and ominous weapon, the Death Star.",
      "poster" : "star_wars_episode_4_poster.png",
      "hero_image" : "star_wars_episode_4_hero.jpg"
    },

    {
      "title" : "Star Wars: Episode V - The Empire Strikes Back",
      "episode_number" : "5",
      "main_characters" : ["Luke Skywalker", "Han Solo", "Princess Leia Organa", "Darth Vader", "C-3P0", "R2-D2", "Chewbacca", "Lando Calrissian", "Boba Fett"],
      "description" : "Fleeing the evil Galactic Empire, the Rebels abandon their new base in an assault with the Imperial AT-AT walkers on the ice world of Hoth. Princess Leia, Han Solo, Chewbacca and the droid C-3PO escape in the Millennium Falcon, but are later captured by Darth Vader on Bespin. Meanwhile, Luke Skywalker and the droid R2-D2 follows Obi-Wan Kenobi's posthumous command, and receives Jedi training from Master Yoda on the swamp world of Dagobah. Will Skywalker manage to rescue his friends from the Dark Lord?",
      "poster" : "star_wars_episode_5_poster.png",
      "hero_image" : "star_wars_episode_5_hero.jpg"
    },

    {
      "title" : "Star Wars: Episode VI - Return of the Jedi",
      "episode_number" : "6",
      "main_characters" : ["Luke Skywalker", "Han Solo", "Princess Leia Organa", "Darth Vader", "C-3P0", "Chewbacca", "The Emperor", "Boba Fett"],
      "description" : "Darth Vader and the Empire are building a new, indestructible Death Star. Meanwhile, Han Solo has been imprisoned, and Luke Skywalker has sent R2-D2 and C-3PO to try and free him. Princess Leia - disguised as a bounty hunter - and Chewbacca go along as well. The final battle takes place on the moon of Endor, with its natural inhabitants, the Ewoks, lending a hand to the Rebels. Will Darth Vader and the Dark Side overcome the Rebels and take over the universe?",
      "poster" : "star_wars_episode_6_poster.png",
      "hero_image" : "star_wars_episode_6_hero.jpg"
    }];


The Movie class looks like this:

export class Movie {
  title: string;
  episode_number: string;
  main_characters: string[];
  description: string;
  poster: string;
  hero_image: string;
}

Now we can test out these predicate methods FirstOrDefault and Where ! Note that in case you have worked with C# and Linq before, the syntax and the Intellisense will make you feel more at home with this kind of code - not only do you have type checking, but you can also pass in strongly typed predicate methods using Typescript, Generics and the Array prototype techniques discussed here. Also note how I define a predicate type here defining an arrow function, being the predicate.

import { Component, Inject } from '@angular/core';
import { StarWarsMovies } from './starwarsmovies';
import { Movie } from './movie';
import './array-extensions';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent {
  title = 'Linq TsExtensions demo';

  firstMovieWithBoba: Movie;
  allMoviesWithLeia: Movie[];
  starwarsMovies: string;

  constructor() {
    this.starwarsMovies = JSON.stringify(StarWarsMovies);
    this.firstMovieWithBoba = 
StarWarsMovies.FirstOrDefault<Movie>(m => m.main_characters.indexOf('Boba Fett') > 0);
    this.allMoviesWithLeia = 
StarWarsMovies.Where<Movie>(m => m.main_characters.indexOf('Princess Leia Organa') > 0);
    console.log(this.firstMovieWithBoba);
    console.log(this.allMoviesWithLeia);
  }

}


We now can work on our strongly typed arrays and define easily our filtering predicates for Where and FirstOrDefault implementation. It should be easy to extend this into more methods, such as SingleOrDefault and Any and so on. The screen shot below shows the results after running ng serve -o:

Thursday, 26 December 2019

Enumerable Range in Javascript

The following Javascript code uses Generator functions and destructuring spread operator ... to create an array between min and count, much similar to Enumerable.Range in Linq and C#. The following screen shot shows how it can be used. You can iterate this with for.. let.. of

function* Range(min,ct) {
  for (let x=min;x<=min+ct;x++) {
    yield x;
  }
}

let gen = [...Range(2,10)]
console.log(gen);

for (let y of gen) {
 console.log(y);
}

Tuesday, 24 December 2019

Generic method for builing a query string of classes in Typescript

This method below can be used in Typescript to build up a query string from a given object of a class instance in Typescript. Use it when performing HTTP(S) GET calls.

  BuildQueryString<T>(input: T): string {
    let q = "?";

    Object.keys(input).forEach(key => q += key + "=" + input[key] + "&");

    if (q.length > 0) {
      q = q.substr(0,q.length-1);
    }

    return q;

    
  }



Sample usage in Angular 8 solution of mine for example:


  async saveSurvey(): Promise<SurveyItem> {
    //debugger
    let s: SurveyItem = {
      Id: 0, LastUpdate: new Date(),
      EquipmentNumber: this.equpimentIdentifier, RoomNumber: this.roomIdentifier,
      PrimaryUsage: this.primaryUsage,
      IsInspected: this.GetBoolean(this.isInspected), IsNotFound: this.GetBoolean(this.isNotFound)
    };
    let q = this.fetcher.GetAPIUrl('savesurvey');
    q += this.fetcher.BuildQueryString(s);
    const response = await this.http.get<SurveyItem>(q, { headers: this.corsHeaders }).toPromise();
    //this.openSnackBar('Lagret utstyr ' + this.equpimentIdentifier);
    this.openSnackBar('Lagret utstyr ' + this.equpimentIdentifier + ' Laster inn liste for utstyr i samme rom også..');

    //After saving survye - update also the properties with updated Id and LastUpdate

    this.SetCurrentSurveyItemPropretiesFromSurveyItem(response);

    this.onRoomSelected(this.roomIdentifier);



    return response;
  }

Monday, 2 December 2019

Eslint Standalone tool

I have created a standalone Eslint tool the last weeks! This tool is available through Npmjs here: https://www.npmjs.com/package/eslint-standalone The source code is available here: https://github.com/toreaurstadboss/eslint-standalone To clone the repo, you can run this command:

git clone https://github.com/toreaurstadboss/eslint-standalone.git

This animated gif shows how the tools shows linting capabilities. The loaded .eslintrc.js file errors if there are ES6 syntax, which does not work well in Internet Explorer. This is done by specifying env->es6 set to true and parserOptions->ecmaVersion set to '5'. Why would you even consider supporting Internet Explorer as a browser for your products ? Well, in the real world, some customers still use Internet Explorer due to company restrictions and compability reasons. So this standalone tool together with .eslintrc.js file below should help you check files conforming to ES5 Syntax and thereby supporting Internet Explorer.

module.exports = {
  "plugins": ["ie11"],
  "env": {
    "browser": true,
    "node": true,
    "es6": false
  },
  "parserOptions": {
    "ecmaVersion": 5,
  },
  "rules": {
    "ie11/no-collection-args": ["error"],
    "ie11/no-for-in-const": ["error"],
    //"ie11/no-loop-func": ["warn"],
    "ie11/no-weak-collections": ["error"]
  }
};

To check that your Javascript code works using this tool, add the .eslinrc.js file above in the folder of your project (or any parent folder on that media disk volume). Then run the command eslint-standalone.exe after adding the .eslintrc.js file. You should then have outputted to the command line the errors (or warnings found) of ES6 Syntax, which IE does not support. Note that I have not added functionality for '--fix' with this ESLint tool yet. You must inspect the warnings and errors reported and manually adjust/fix the Javascript source code. Also note that this tool only supports looking at .js and .htm and .html files. I tried adding .cshtml files in the list of file globs supported, but the tool could not understand Razor syntax. Feel free to give me some tips here if you know how to add this as a support. Also note that it is additional documentation to be found for this tool on the Npmjs.org site and also in the GitHub repository.
eslint-standalone.exe 
The sample screen shot shows how to run the tool from the command line (simple command). I deliberately added an arrow method in a Javascript file and the tool quickly spots this issue. For a medium sized project the tool takes only 5-10 seconds to execute.

Friday, 15 November 2019

Sorting array word-wise in Javascript

Sometimes it is nice to sort arrays word-wise in Javascript. This means sorting not the entire column value,

/**
 * Summary: Sorts alphabetaically word-wise to be used in e.g. a Select2Js control. Specify the n-word to start sorting with. 
 *
 * Alphabetically sorts by each word
 * @param {Number}   startWordIndex The 'n-word' to begin sorting with  *
 * @param {boolean}  isAscending The direction of sorting - true means ascending, false means descending
 * @return {type} Return sort comparison value. If 0, the sorting is tie, if < 0 the element a preceeds b
 */
(function () {
    var sortFunction = function sortFunctionTemplate(isAscending, startWordIndex, valueSelector, a, b) {
        var aValue = valueSelector(a);
        var bValue = valueSelector(b);
        var astripped = aValue.split(' ');
        var bstripped = bValue.split(' ');
        var wordLength = Math.min(astripped.length, bstripped.length);

        var compareValue = 0;
        for (var i = startWordIndex; i < wordLength; i++) {
            compareValue = astripped[i].localeCompare(bstripped[i]);
            if (compareValue !== 0) {
                break;
            }
        }
        if (compareValue === 0) {
            if (astripped.length > bstripped.length) {
                compareValue = 1;
            } else if (astripped.length < bstripped.length) {
                compareValue = 1;
            }
        }
        return compareValue * (isAscending ? 1 : -1);
    };
    if (typeof (Array.prototype.sortWordwise) === 'undefined') {
        // ReSharper disable once NativeTypePrototypeExtending
        Array.prototype.sortWordwise = function sortWordwise(startWordIndex, isAscending, valueSelector) {
            if (valueSelector === null) {
                valueSelector = function (item) {
                    return item;
                };
            }
            //console.log('sorterer word-wise... ');

            return this.sort(sortFunction.bind(this, isAscending, startWordIndex, valueSelector));

        };

    }
})();

Example how to use this method: Here we use the Select2.js jQuery plugin to do our custom sorting to sort word-wise. I only consider the text after the ':' in my specific use case and I supply the starting index - sorting by the nth-word 1 (i.e. second word and so on) and supply a value selector function also. Select2.Js also retrieves a matcher function to specify the matching to be done case-insensitive (the find item in list function of the select 2 js control in this specific case).

$('.stentGraftfabrikatpicker').select2({
      width: "element",
            sortResults: function(data) {
                var velgVerdi = data[0];
                var ret = [velgVerdi];
                var dataToBeSorted = data.splice(1);
                return ret.concat(
                    dataToBeSorted.sortWordwise(1, true, function(item) {
                        var value = item.text;
                        return value.indexOf(':') >= 0 ? value.substring(value.indexOf(':') + 1) : value;
                    })
                );
            },
      matcher: function(term, text) {
       return text.toUpperCase().indexOf(term.toUpperCase()) >= 0;
      },
      allowClear: true
    });

AngularJS Directive for Focus trap for modal popups

If you use Bootstrap modal popup, chances are that hitting TAB enough types on the keyboard will navigate out of the modal popup and back to the background web page, the DOM elements "beneath" the modal popup. This AngularJS directive should fix up that, wrapping everything in an IFE (Immediately invoking Function Expression). Note that this only works if your module is called 'app' (the default name).

(function() {
angular.module('app')
 .directive('modal', trapFocus)
 
 function trapFocus() {
        return {
            restrict: 'C',
            priority: 1,
            link: function (scope, element, attr) {
                if (typeof (scope.registerFocusTrap) === 'undefined') {
                    scope.registerFocusTrap = registerFocusTrap;
                } else {
                    for (var i = 0; i < element.length; i++) {
                        registerFocusTrap(element.get(i));
 
                    }
                }
 
            }
        };
    }
 
    function registerFocusTrap(element) {
        var focusableEls = element.querySelectorAll(
            'a[href]:not([disabled]), button:not([disabled]), textarea:not([disabled]), input[type="text"]:not([disabled]), input[type="radio"]:not([disabled]), input[type="checkbox"]:not([disabled]), select:not([disabled])');
        var firstFocusableEl = focusableEls[0];
        var lastFocusableEl = focusableEls[focusableEls.length - 1];
        // ReSharper disable once InconsistentNaming
        var KEYCODE_TAB = 9;
 
        $(element).on('keydown',
            function (e) {
                console.log('inside registerFocusTrap keydown');
                var isTabPressed = (e.key === 'Tab' || e.keyCode === KEYCODE_TAB);
 
                if (!isTabPressed) {
                    return;
                }
 
                if (e.shiftKey) /* shift + tab */ {
                    if (document.activeElement === firstFocusableEl) {
                        lastFocusableEl.focus();
                        e.preventDefault();
                    }
                } else /* tab */ {
                    if (document.activeElement === lastFocusableEl) {
                        firstFocusableEl.focus();
                        e.preventDefault();
                    }
                }
            }
        );
    }
  
}); 
 

Note that the name of registered modules in AngularJs is not supported in AngularJs by itself. This polyfill should tough fix up this.

(function(orig) {
    angular.modules = [];
    angular.module = function() {
        if (arguments.length > 1) {
            angular.modules.push(arguments[0]);
        }
        return orig.apply(null, arguments);
    }
})(angular.module);

Sunday, 10 November 2019

Implementing projection in Javascript

Github page for source code in this article:
https://github.com/toreaurstadboss/JsLinqSimpleProjection
https://www.npmjs.com/package/jslinqsimpleprojection
Npm package for source code in this article: Since I started working with Linq in C#, I missed a good way of doing much of the same functionality in Javascript. Today, there are several Linq libraries for Javascript and Typescript, and libraries such as Backbone.Js or Lodash also containing a lot of helpful operators or utility methods. As an educational exercise, I was looking into a simple way of doing a projection method in pure Javascript (no es6 syntax). Here is what I made. First off, we need to be able to project an array of objects by listing up properties. In ES6 Javascript we could use arrow functions. But I wanted to support pure Javascript. So I choose to use a comma separated list of property or field values to dive into the array object, written in Json notation of course. Consider first this array as an example:

        var someCountries = [
          { country: "Norway", population: 5.2, code: "NO" },
          { country: "Finland", population: 5.5, code: "SU" },
          { country: "Iceland", population: 0.4, code: "IC" },
          { country: "Sweden", population: 10.2, code: "SW" }
        ];

We want to project this array using a new method select on the array of which we use the Array.prototype to achieve. Note that this will immediately add methods to all array objects immediately in the global scope. Now consider a projection of just the 'country' and the 'population' fields of the Json structure. Given a method call of just these two properties, we want to create a select projection method. First consider this lightweight linqmodule implementation, using an IFE (Immediately invoked function expression) and using the revealing module pattern. We expose the method dump to this module.

var linqmodule = (function() {
  projection = function(members) {
    var membersArray = members.replace(/s/g, "").split(",");
    var projectedObj = {};

    for (var i = 0; i < this.length; i++) {
      for (var j = 0; j < membersArray.length; j++) {
        var key = membersArray[j];
        if (j === 0) {
          projectedObj[i] = {};
        }
        projectedObj[i][key] = this[i][key];
      }
    }

    return projectedObj;
  };
  Array.prototype.select = projection;

  dumpmethod = function(arrayobj) {
    var result = "";
    result += "[";

    for (var i = 0; i < Object.keys(arrayobj).length; i++) {
      var membersArray = Object.keys(arrayobj[i]);
      for (var j = 0; j < membersArray.length; j++) {
        if (j === 0) {
          result += "{";
        }
        var key = membersArray[j];
        result +=
          "key: " +
          key +
          " , value: " +
          arrayobj[i][key] +
          (j < membersArray.length - 1 ? " , " : "");
        if (j === membersArray.length - 1) {
          result +=
            "}" + (i < Object.keys(arrayobj).length - 1 ? "," : "") + "\n";
        }
      }
    }
    result += "]";

    return result;
  };

  return {
    dump: dumpmethod
  };
})();


Now it is easy to dump the contents of our projected array (which is copied into a new object) using the dump method:

 result = someNums.select("country,population");
         document.getElementById("result").innerText = linqmodule.dump(result);

        console.log(result);

Note that our new object contains only the country and population fields in the Json structure, not the code. We have created a simple projection mechanism in Javascript in a self contained module!

Arithmetic parser in Javascript

I just added an arithmetic parser in Javascript code sample on Github, check out the following repo: JsSimpleParser The parser is also available through Npm: https://www.npmjs.com/package/simplejsparsermatharithmetic Installation: npm i simplejsparsermatharithmetic Supported expressions (examples): 2+3 should evaluate to 5 12 * 5–(5 * (32 + 4)) + 3 should evalute to -117 This is a great example of how to write a parser of your own.

Sunday, 13 October 2019

Using TagBuilder in MVC

I have been started programming MVC again at work after many years focusing more on WPF. So I came accross a class called 'TagBuilder'. This is a handy class for generating markup programatically. Let us create a HTML helper that renders an image tag. It can use TagBuilder to achieve this. First off, we create the HTML helper like this:
using System.Web;
using System.Web.Mvc;

namespace HelloTagBuilderDemo.Helpers
{
    /// <summary>
    /// Sample usage of TagBuilder in MVC
    /// </summary>
    public static class HtmlHelpers
    {
        /// <summary>
        /// Generates an IMG element which is self-closing and uses as src the given path pointing to an image file with a relative path within the web application
        /// and with alternate text
        /// </summary>
        /// <param name="path"></param>
        /// <param name="alternateText"></param>
        /// <returns></returns>
        // ReSharper disable once UnusedParameter.Global
        // ReSharper disable once InvalidXmlDocComment
        public static IHtmlString Image(this HtmlHelper htmlHelper, string path, string alternateText)
        {
            var builder = new TagBuilder("img");
            // ReSharper disable once StringLiteralTypo
            builder.Attributes.Add("src", VirtualPathUtility.ToAbsolute(path));
            builder.Attributes.Add("alt", alternateText);
            var markupResult = builder.ToString(TagRenderMode.SelfClosing);
            return new MvcHtmlString(markupResult);
        }
    }
}

We make use of the VirtualPathUtility.ToAbsolute method to convert a virtual path to an absolute path. Then we make use of the html helper inside a MVC view like this:

@{
    ViewBag.Title = "Home Page";
}

@using System.Web.Mvc.Html
@using HelloTagBuilderDemo.Helpers


<div class="jumbotron">
    <h1>ASP.NET</h1>
    <p class="lead">ASP.NET is a free web framework for building great Web sites and Web applications using HTML, CSS and JavaScript.</p>
    <p><a href="https://asp.net" class="btn btn-primary btn-lg">Learn more »</a></p>
</div>

<div class="row">
    <div class="col-md-4">
        <h2>Getting started</h2>
        <p>Harold is at it again, making clones of himself to inflict multiple pain.</p>                
    </div>
    <div class="col-md-4">
        @Html.Image(@"~/Images/haroldatitagain.jpg", "Harold")
    </div>
</div>
And now we have our resulting HTML helper at display, showing also in the screen grab the markup the HTML helper generated for us. [1] Tagbuilder on MSDN: https://docs.microsoft.com/en-us/dotnet/api/system.web.mvc.tagbuilder?view=aspnet-webpages-3.2

Sunday, 29 September 2019

Deleting a set of databases with similar names with T-SQL

Devops Sunday. If you end up having many databases in SQL Server and want to get rid of them by matching their names, this T-SQL should help you out.

use master
go
declare @tablestoNuke as table(db nvarchar(100))
insert into @tablestoNuke
select name from sys.databases  
where name like '%SomeSimilarDbNameSet%'
declare @nukedb as nvarchar(100)
declare @nukesql as nvarchar(150)

declare nuker cursor for
select db from @tablestoNuke

open nuker
fetch next from nuker into @nukedb

while @@FETCH_STATUS = 0 
begin
set @nukesql = 'drop database ' + @nukedb
exec sp_executesql @nukesql
fetch next from nuker into @nukedb
end

close nuker
deallocate nuker

print 'All done nuking'


The T-SQL uses a cursor to loop through the database names fetched from sys.databases view on master db and then uses exec sp_executesql to delete the databases, by dropping them.

Tuesday, 24 September 2019

Getting started with tests on controllers in AngularJs

Some notes - I had to work with AngularJs tests today and needed to look into Jasmine and mocking enough and import enough to have running tests. I use the Chutzpah test runner to run the Jasmine Tests. The unit test below should get you started writing tests for controllers in AngularJs. The key concepts is to import jQuery, Bootstrap, Angular Animate, Angular-Mocks and your module and controller through using the reference path syntax at the top and then define a beforeEach that capture the _$controller_ and $_rootScope_ variables and using $rootScope.$new() to create a scope. But in my case I also had to specify a provided factory 'bootstrappedData' since my controller reads the 'model' property inside that. By specifying the value this provided factory returns at the top of each tests, I got the amount of DRY I needed to get started testing. I had to this since my controller got the data in an indirect manner, using he factory. I then create a new instance of the controller after updating the 'bootstrappedData' factory.

/// 
/// 
/// 
/// 
/// 
/// 
/// 

describe('someController works', function () {
    beforeEach(module('app'));
    var $scope;
    var $rootScope;
    var $controller;
    var $bootstrappedData;
    var $repository;
    var ctrl;
    var provide;

    beforeEach(module(function ($provide) {
        provide = $provide;
      
    }));

    beforeEach(module(function ($provide) {
        $provide.factory('repository', function () {
            return {
                model: {
                }
            };
        });
    }));

    beforeEach(inject(function (_$controller_, _$rootScope_) {
        $controller = _$controller_;
        $rootScope = _$rootScope_;
        scope = $rootScope.$new();

    }));

    it('Creates the AngularJs controller someController', function () {
        provide.factory('bootstrappedData', function () {
            return {
                model: {
                }
            };
        });

        ctrl = $controller('someController', { $scope: scope });
        expect(ctrl).not.toBe(null);

    });

    it('Method someproperty returns expected', function () {
        provide.factory('bootstrappedData', function () {
            return {
                model: {
                    SomeProperty: '3'
                }
            };
        });
        ctrl = $controller('KontrollskjemaController', { $scope: scope });
        var someprop = scope.isSomeConditionalPropertyReturningTrueIfSomePropertyIsThree;
        expect(someprop).toBe(true);
    });

});


A tip is to add a file called Chutzpah.json and ignoring well known Javascript libraries to only run code coverage on your own code:

{
  "CodeCoverageExcludes": [ "*\\jquery.js", "*\\angular.js", "*\\bootstrap.min.js", "*\\jquery*", "*\\angular-animate.min.js" ]
  //"CodeCoverageIncludes": [ "*\\*Spec.js" ]
}