.Net 6 : Jwt Authentication in Minimal Web Api

In the previous post, we delved into Jwt Authentication implementation in the .Net Core 5. In this post, we will create a Minimal Web API (introduced in .Net 6) and implement Jwt Authentication in it.

Minimal Web API allows developers to build low ceremony web apis without the overhead of ceremonial code in traditional Asp.Net core MVC solution. The traditional Web API core adds so much ceremonial code to your application that it could confuse the beginners.Starting with .Net 6 Preview 4, you can build minimal API’s which are devoid of any ceremonial code – write only what you want !!

You can create a minimal Web Api solution using the following command

dotnet new web

This would provide you the basic skeleton for the project. The code is build on the Top Level Programs feature introduced in C# 9, which allows you to declare and execute programs without the need for writing ceremonial code like class and namespace or main.

So let us write our minimal Web Api for implementing Jwt Authentication now.

var builder = WebApplication.CreateBuilder(args);
await using var app = builder.Build();

if (app.Environment.IsDevelopment())
{
    app.UseDeveloperExceptionPage();
}

app.MapGet("/", (Func<string>)(() => "This a demo for JWT Authentication using Minimalist Web API"));
await app.RunAsync();

A minimal code Web Api could look like the above. Isn’t that clean ?

Dependency Injection

To add authentication, we would add couple of services which would help us on the way. First we will add a ITokenService which would provide us the token. We will also add IUserRepositoryService which would allow us to mock the users for sake of example (let us not complicate things with a Db here).

But first we need to add a nuget package which would allow us to use Dependency injection – Microsoft.Extensions.DependencyInjection.

At this point, we will make use of another .Net 6 feature – Global using. This would allow us to move all our using statements to a single location and allow further clean up code. Read on Global using here.

Add a new file called “Usings.cs” and move all your using statements.

global using System;
global using System.ComponentModel.DataAnnotations;
global using Microsoft.AspNetCore.Builder;
global using Microsoft.AspNetCore.Http;
global using Microsoft.Extensions.Hosting;
global using System.Collections.Generic;
global using System.Linq;
global using Microsoft.Extensions.DependencyInjection;
global using System.Security.Claims;
global using System.Text;
global using Microsoft.IdentityModel.Tokens;
global using System.IdentityModel.Tokens.Jwt;
global using Microsoft.AspNetCore.Authentication.JwtBearer;
global using Microsoft.AspNetCore.Authorization;

Alright back to the task in our hand. With the package of Dependency Injection added, we can now register our services.

builder.Services.AddSingleton<ITokenService>(new TokenService());
builder.Services.AddSingleton<IUserRepositoryService>(new UserRepositoryService());

For sake of example, we will use the same implementation of TokenService and UserRepositoryService as we had used in the earlier post on Jwt authentication.



public interface IUserRepositoryService
{
    UserDto GetUser(UserModel userModel);
}
public class UserRepositoryService : IUserRepositoryService
{
    private List<UserDto> _users => new ()
    {
        new ("Anu Viswan","anu"),
        new ("Jia Anu","jia"),
        new ("Naina Anu","naina"),
        new ("Sreena Anu","sreena"),
    };
    public UserDto GetUser(UserModel userModel)
    {
        return _users.FirstOrDefault(x => string.Equals(x.UserName,userModel.UserName) && string.Equals(x.Password, userModel.Password));
    }
}

public interface ITokenService
{
    string BuildToken(string key, string issuer, UserDto user);
}
public class TokenService : ITokenService
{
    private TimeSpan ExpiryDuration = new TimeSpan(0, 30, 0);
    public string BuildToken(string key, string issuer, UserDto user)
    {
        var claims = new[]
        {
                new Claim(ClaimTypes.Name, user.UserName),
                new Claim(ClaimTypes.NameIdentifier,
                Guid.NewGuid().ToString())
             };

        var securityKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(key));
        var credentials = new SigningCredentials(securityKey, SecurityAlgorithms.HmacSha256Signature);
        var tokenDescriptor = new JwtSecurityToken(issuer, issuer, claims,
            expires: DateTime.Now.Add(ExpiryDuration), signingCredentials: credentials);
        return new JwtSecurityTokenHandler().WriteToken(tokenDescriptor);
    }
}

We will also use two POCO’s which would help us transfer data.

public record UserDto(string UserName,string Password);

public record UserModel
{
    [Required]
    public string UserName { get; set; }

    [Required]
    public string Password { get; set; }
}

Note that we are using another .Net 5 feature here – record.

Add Middleware

The next step would be to configure and add the middleware for supporting Authentication and Authorization.

builder.Services.AddAuthorization();
builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme).AddJwtBearer(opt =>
{
    opt.TokenValidationParameters = new ()
    {
        ValidateIssuer = true,
        ValidateAudience = true,
        ValidateLifetime = true,
        ValidateIssuerSigningKey = true,
        ValidIssuer = builder.Configuration["Jwt:Issuer"],
        ValidAudience = builder.Configuration["Jwt:Issuer"],
        IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(builder.Configuration["Jwt:Key"]))
    };
});

We will use the WebApplicationBuilder instance to configure our middleware and use the the WebApplication instance to plugin our middleware.

app.UseAuthentication();
app.UseAuthorization();

Actions

Now we are all set to write our Login and Protected Action. We will first write our Login Action.

app.MapGet("/login", [AllowAnonymous] async (HttpContext http,ITokenService tokenService,IUserRepositoryService userRepositoryService) => {
    var userModel = await http.Request.ReadFromJsonAsync<UserModel>();
    var userDto = userRepositoryService.GetUser(userModel);
    if (userDto == null)
    {
        http.Response.StatusCode = 401;
        return;
    }

    var token = tokenService.BuildToken(builder.Configuration["Jwt:Key"], builder.Configuration["Jwt:Issuer"], userDto);
    await http.Response.WriteAsJsonAsync(new { token = token });
    return;
});

Notice we have also made use of Dependency Injection to use our services, which had registered in the previous steps. We then use the UserRepositoryService and TokenService to validate and generate token for our User.

Another important point to note here is how we used the [AllowAnonymous] attribute inline.

The protected action doesn’t do much. We have kept it as simple as possible for sake of the example.

app.MapGet("/doaction", (Func<string>)([Authorize]() => "Action Succeeded"));

That’s all you need to do to implement Jwt Authentication using Minimal API. The whole implementation looks like the following.


var builder = WebApplication.CreateBuilder(args);
builder.Services.AddSingleton<ITokenService>(new TokenService());
builder.Services.AddSingleton<IUserRepositoryService>(new UserRepositoryService());
builder.Services.AddAuthorization();
builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme).AddJwtBearer(opt =>
{
    opt.TokenValidationParameters = new ()
    {
        ValidateIssuer = true,
        ValidateAudience = true,
        ValidateLifetime = true,
        ValidateIssuerSigningKey = true,
        ValidIssuer = builder.Configuration["Jwt:Issuer"],
        ValidAudience = builder.Configuration["Jwt:Issuer"],
        IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(builder.Configuration["Jwt:Key"]))
    };
});

await using var app = builder.Build();
app.UseAuthentication();
app.UseAuthorization();

if (app.Environment.IsDevelopment())
{
    app.UseDeveloperExceptionPage();
}

app.MapGet("/", (Func<string>)(() => "This a demo for JWT Authentication using Minimalist Web API"));

app.MapGet("/login", [AllowAnonymous] async (HttpContext http,ITokenService tokenService,IUserRepositoryService userRepositoryService) => {
    var userModel = await http.Request.ReadFromJsonAsync<UserModel>();
    var userDto = userRepositoryService.GetUser(userModel);
    if (userDto == null)
    {
        http.Response.StatusCode = 401;
        return;
    }

    var token = tokenService.BuildToken(builder.Configuration["Jwt:Key"], builder.Configuration["Jwt:Issuer"], userDto);
    await http.Response.WriteAsJsonAsync(new { token = token });
    return;
});

app.MapGet("/doaction", (Func<string>)([Authorize]() => "Action Succeeded"));

await app.RunAsync();

public record UserDto(string UserName,string Password);

public record UserModel
{
    [Required]
    public string UserName { get; set; }

    [Required]
    public string Password { get; set; }
}

public interface IUserRepositoryService
{
    UserDto GetUser(UserModel userModel);
}
public class UserRepositoryService : IUserRepositoryService
{
    private List<UserDto> _users => new ()
    {
        new ("Anu Viswan","anu"),
        new ("Jia Anu","jia"),
        new ("Naina Anu","naina"),
        new ("Sreena Anu","sreena"),
    };
    public UserDto GetUser(UserModel userModel)
    {
        return _users.FirstOrDefault(x => string.Equals(x.UserName,userModel.UserName) && string.Equals(x.Password, userModel.Password));
    }
}

public interface ITokenService
{
    string BuildToken(string key, string issuer, UserDto user);
}
public class TokenService : ITokenService
{
    private TimeSpan ExpiryDuration = new TimeSpan(0, 30, 0);
    public string BuildToken(string key, string issuer, UserDto user)
    {
        var claims = new[]
        {
                new Claim(ClaimTypes.Name, user.UserName),
                new Claim(ClaimTypes.NameIdentifier,
                Guid.NewGuid().ToString())
             };

        var securityKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(key));
        var credentials = new SigningCredentials(securityKey, SecurityAlgorithms.HmacSha256Signature);
        var tokenDescriptor = new JwtSecurityToken(issuer, issuer, claims,
            expires: DateTime.Now.Add(ExpiryDuration), signingCredentials: credentials);
        return new JwtSecurityTokenHandler().WriteToken(tokenDescriptor);
    }
}


You can find the code given in the example in my Github.

That’s all for now, Happy weekend !!

Jwt Authentication using .Net Core 5

In this blog post we will look into JWT Authentication and its implementation using .Net Core Web Api. We will try to keep things as simple as possible, while taking time to explain the key concepts in best possible way. For same reason, we will mock our User repository with static entries.

Json Web Token

Json Web Token or JWT is an open standard for securely transmitting self contained messages between parties as Json Objects. These messages are verifiable as they are digitally signed. They are extremely compact compared to Simple Web Tokens (SWT) and could be used for Authentication as well as information exchange.

  • Authentication – After the initial sign in, each request send by client would contain JWT token, which would be read and used by the Server for authorization.
  • Information Exchange – Multiple parties could exchange secure information as they digitally signed. The signature component of the JWT(we will get it shortly) contains the hash of header and payload ensuring the message is not tampered with.

Structure of JWT

The key structure of JWT contains three parts in the following format.

Header.Payload.Signature

Let us examine each part.

Header – The Header contains information on the type of token and the hashing algorithm used. Typical header might look like

{
    'alg':'H256',
    'typ':'Jwt'
}

Payload – Payload contains claims, which are information about the entity and any additional information required. Claims are broadly categorized into 3 types.

  • Registered Claims – A set of predefined non-mandatory claims which can used to provide useful information.
  • Public Claims – Custom claims which are defined and registered with IANA (Internet Assigned Numbers Authoriry) Json web Token registry.
  • Private Claims – Custom claims which are defined and used by parties, but are neither predefined or registered.

Typical Payload might look like

{
    "iss":"www.hello.com",
    "sub":"123456",
    "name":"John Doe",
    "admin":true
}

Signature – The third and final part of JWT token structure is known as Signature. This comprises of Base64 encoded Header and Payload, which is then applied with the algorithm specified in the header with a secret key. The signed part ensure that the message wasn’t tampered with. Typical signature might look like

HMACSHA256( base64(header) + "." +   base64(payload), secret)

How does JWT Token work.

JWT authentication works in a simple way.

  • During the authentication process, the user inputs (username/password) are validated by the server and a token is generated. This token is then send back to the caller.
  • Caller stores the token internally and for each susequent request for a protected resource, it would include the token in the Authorization Header using the Bearer Schema.
  • The server would validate the further requests based on the token recieved. It would allow the request to access the protected source if the token is successfully validate.

Implementation of JWT Token in .Net Core 5 Web Api.

Alright, enough of talkng about JWT. Let us now start writing some code.

The first step would be to store our secret key and algorithm for signature in the AppSettings.Json, along with any additional information required. This might typically look like

"Jwt": {
    "Key": "ThisWouldBeReplacedBySecretKey",
    "Issuer": "www.bytelanguage.net",
    "Audience": "http://www.hello.com"
  }

We will now proceed to configure the authentication service and schema. The authentication is done using the IAuthenticationService which provides the ClaimPrincipal instance for the authorization to take decisions against. Schema refers to the authentication handlers and options for configuring each handler.

The Authentication Handlers create the Authentication ticket which represents the User Identity. Additionally it returns no result/failure when the Authentication fails. It also executes the challenge or forbid actions when an protected resource is accessed.

We configure the service and schema using the ConfigureService method.

 services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme).AddJwtBearer(opt =>
{
    opt.TokenValidationParameters = new Microsoft.IdentityModel.Tokens.TokenValidationParameters
    {
        ValidateIssuer = true,
        ValidateAudience = true,
        ValidateLifetime = true,
        ValidateIssuerSigningKey = true,
        ValidIssuer = Configuration["Jwt:Issuer"],
        ValidAudience = Configuration["Jwt:Issuer"],
        IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(Configuration["Jwt:Key"]))
    };
});

In the above code, we have added registered the service required for authentication along with the Schema. AddAuthentication method registers the service used for authentication and returns a AuthenticationBuilder instance which can be further used for configuring the authentication. We have also specified that the JwtBearer would be responsible for authenticating the credentials using the token extracted from the Authorization Header, using the AddJwtBearer extension method.

.Net Core uses middlewares for handling Authentication and authorizations. The next step involves ensuring the Authentication and Authorization middlewares are plugged in our execution pipeline. This is done using the Configure() method.

app.UseAuthentication();
app.UseAuthorization();

A word of caution here. Since the middlewares are typically executed in the order they are registered, you need to ensure that the Authentication/Authorization middleware are in their right place. Usually you would want them after the routing middleware, and before the end points middleware.

Now that we have defined and registered our middlewares, it is time to define couple of services.

  • TokenService : which would be responsible for generating the token.
  • UserRepositoryService : Which would mock the user repository for us (Remember, as mentioned in the earlier part of article, we are not using any actual db in this example)

TokenService

The Token Service comprises of a single method.

public interface ITokenService
{
    string BuildToken(string key, string issuer, UserDto user);
}

The method would accept a secret key, an issuer and the UserDto, and would return a string representing the Jwt Token.

Let us go ahead and implement the service now.

public class TokenService : ITokenService
{
    private TimeSpan ExpiryDuration = new TimeSpan(0, 30,0);
    public string BuildToken(string key, string issuer, UserDto user)
    {
        var claims = new[]
        {
            new Claim(ClaimTypes.Name, user.UserName),
            new Claim(ClaimTypes.Role, user.Role),
            new Claim(ClaimTypes.NameIdentifier,
            Guid.NewGuid().ToString())
            };

        var securityKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(key));
        var credentials = new SigningCredentials(securityKey, SecurityAlgorithms.HmacSha256Signature);
        var tokenDescriptor = new JwtSecurityToken(issuer, issuer, claims,
            expires: DateTime.Now.Add(ExpiryDuration), signingCredentials: credentials);
        return new JwtSecurityTokenHandler().WriteToken(tokenDescriptor);
    }
}

In the above code, we have created a set of Claims representing the User identity. We have also set a expiry for the token and then used the HmacSha256 algorithm to sign the token.

Repository Service

As mentioned earlier, this would be a simple class which would mock the User repository for us (as we do not want to complicate the example in hand with use of Db). For same reason, we will keep it as simple as possible.

public interface IUserRepositoryService
{
    UserDto GetUser(UserModel userModel);
}

public class UserRepositoryService:IUserRepositoryService
{
    private List<UserDto> _userCollection = new List<UserDto>();
    public UserRepositoryService()
    {
        _userCollection.AddRange(new[]
        {
            new UserDto("Anu Viswan","anu","admin"),
            new UserDto("Jia Anu","jia","admin"),
            new UserDto("Naina Anu","naina","admin"),
            new UserDto("Sreena Anu","sree","admin"),
        });
    }

    public UserDto GetUser(UserModel userModel)
    {
        return _userCollection.Single(x=>string.Equals(x.UserName,userModel.UserName) && string.Equals(x.Password,userModel.Password));
    }
}

The service exposes a method called GetUserModel which would accept a POCO and return the a User Dto representing User with same user name (and password – effectively validating)mentioned in the POCO. The UserModel and UserDto are defined as

public record UserModel
{
    [Required]
    public string UserName { get; set; }

    [Required]
    public string Password { get; set; }
}

public record UserDto(string UserName,string Password,string Role)
{
}

Withour services in place, it is time to ensure we have ability to inject them into our controllers. We do this by adding into our ServiceCollection using the ConfigureServices() method.

services.AddTransient<ITokenService, TokenService>();
services.AddTransient<IUserRepositoryService, UserRepositoryService>();

We can now inject them our constructor.

private readonly ITokenService _tokenService;
private readonly IUserRepositoryService _userRepositoryService;
private readonly IConfiguration _configuration;
public HomeController(ITokenService tokenService,IUserRepositoryService userRepositoryService,IConfiguration config )
{
    _tokenService = tokenService;
    _userRepositoryService = userRepositoryService;
    _configuration = config;
}

Login Action

Now we have almost everything that we require for authentication and generation of token. We have registered and configured our middlewares, and so have created service for token generation. Let us now write the Login action which would used by the clients for logging into the system.

[AllowAnonymous]
[Route("login")]
[HttpPost]
public ActionResult Login(UserModel userModel)
{
    if(string.IsNullOrEmpty(userModel.UserName) || string.IsNullOrEmpty(userModel.Password))
    {
        return RedirectToAction("Error");
    }

    IActionResult response = Unauthorized();
    var user = _userRepositoryService.GetUser(userModel);

    if(user != null)
    {
        var generatedToken = _tokenService.BuildToken(_configuration["Jwt:Key"].ToString(), _configuration["Jwt:Issuer"].ToString(), user);
        return Ok(new
        {
            token = generatedToken,
            user = user.UserName
        });

    }
    return RedirectToAction("Error");
}

private UserDto GetUser(UserModel userModel)
{
    return new UserDto("Jia", "admin", "admin");

}

Notice that we have applied the [AllowAnonymous] attribute to the action. This instructs that the action is an unprotected resource and could be accessed by an non-authenticated user. This is of course required, otherwise the user will never be able authenticate himself.

As seen in the code above, we retrieve the UserRepository Service to retrieve the User Dto using the data we received from the client. The validated user would then generated a token using the ITokenService.

var generatedToken = _tokenService.BuildToken(_configuration["Jwt:Key"].ToString(), _configuration["Jwt:Issuer"].ToString(), user);

At this point, we are also retrieving the configuration information we had stored in the AppSettings.Json in the first step, including the secret key. The Generated token is then send back to the caller.

Authorizing the Protected resources

We decorate the protected resources using the [Authorize] attribute to specify that they need authentication. For example,

[Authorize]
[Route("Secret")]
[HttpPost]
public ActionResult SecretFunction()
{
    return Ok("Alright, you are authorized user");
}

The Action Secret can be now accessed only by an authenticated user. The authentication handlers would execute a Challenge/Forbid action every time an unauthorized user attempts to access a protected resource.

That was a brief walk through for implementing Jwt authentication using .Net Core 5. The code in the post could can be found in my github here. The complete process can be summarized as the following.

JWT Authentication

Cheat Code for Database Meta information : PostgreSql

In an earlier post we looked at the Queries for Sql Server for retrieving meta information. In this post, we will look at the PostgresSql version.

Get All Views

SELECT table_name,
       view_definition
FROM   information_schema.VIEWS
WHERE  table_schema = ANY ( Current_schemas(FALSE) );  

Get All Tables

SELECT table_name
FROM   information_schema.TABLES
WHERE  table_schema = ANY ( Current_schemas(FALSE) ) 

Get All Columns

SELECT column_name,
       is_nullable,
       is_identity,
       character_maximum_length,
       numeric_precision,
       numeric_precision_radix,
       numeric_scale,
       data_type
FROM   information_schema.COLUMNS
WHERE  table_schema = 'public'
       AND table_name = '<TableName>'  

Get All Indices from database

SELECT ix.indisunique AS IsUnique,
       t.relname      AS TableName,
       i.relname      AS Name,
       a.attname      AS ColumnName
FROM   pg_class t,
       pg_class i,
       pg_index ix,
       pg_attribute a
WHERE  t.oid = ix.indrelid
       AND i.oid = ix.indexrelid
       AND a.attrelid = t.oid
       AND a.attnum = ANY ( ix.indkey )
       AND t.relkind = 'r'
       AND ix.indisprimary = FALSE
       AND t.relname = '<TableName>';  

Get All Primary Key Constraints

SELECT kcu.table_schema,
       tco.constraint_name,
       kcu.column_name
FROM   information_schema.table_constraints tco
       join information_schema.key_column_usage kcu
         ON kcu.constraint_name = tco.constraint_name
            AND kcu.constraint_schema = tco.constraint_schema
            AND kcu.constraint_name = tco.constraint_name
WHERE  tco.constraint_type = 'PRIMARY KEY'
       AND kcu.table_name = '<TableName>'
ORDER  BY kcu.table_schema,
          kcu.table_name  

Get all Unique Key Constraints

SELECT kcu.table_schema,
       tco.constraint_name,
       kcu.column_name
FROM   information_schema.table_constraints tco
       join information_schema.key_column_usage kcu
         ON kcu.constraint_name = tco.constraint_name
            AND kcu.constraint_schema = tco.constraint_schema
            AND kcu.constraint_name = tco.constraint_name
WHERE  tco.constraint_type = 'UNIQUE'
       AND kcu.table_name = '<TableName>'
ORDER  BY kcu.table_schema,
          kcu.table_name;  

Get all check constraints

 SELECT col.column_name    AS ColumnName,
       tc.constraint_name AS Name,
       cc.check_clause    AS DEFINITION
FROM   information_schema.table_constraints tc
       join information_schema.check_constraints cc
         ON tc.constraint_schema = cc.constraint_schema
            AND tc.constraint_name = cc.constraint_name
       join pg_namespace nsp
         ON nsp.nspname = cc.constraint_schema
       join pg_constraint pgc
         ON pgc.conname = cc.constraint_name
            AND pgc.connamespace = nsp.oid
            AND pgc.contype = 'c'
       join information_schema.COLUMNS col
         ON col.table_schema = tc.table_schema
            AND col.table_name = tc.table_name
            AND col.ordinal_position = ANY ( pgc.conkey )
WHERE  tc.constraint_schema NOT IN( 'pg_catalog', 'information_schema' )
ORDER  BY tc.table_schema,
          tc.table_name;  

Get all Foreign Key Constraints

 SELECT tc.constraint_name,
       kcu.column_name,
       ccu.table_name,
       ccu.column_name
FROM   information_schema.table_constraints AS tc
       join information_schema.key_column_usage AS kcu
         ON tc.constraint_name = kcu.constraint_name
            AND tc.table_schema = kcu.table_schema
       join information_schema.constraint_column_usage AS ccu
         ON ccu.constraint_name = tc.constraint_name
            AND ccu.table_schema = tc.table_schema
WHERE  tc.constraint_type = 'FOREIGN KEY'
       AND tc.table_name = '<TableName>'  

Get all Default value Constraints

 SELECT col.column_name    AS ColumnName,
       col.column_default AS DefaultValue
FROM   information_schema.COLUMNS col
WHERE  col.column_default IS NOT NULL
       AND col.table_schema NOT IN( 'information_schema', 'pg_catalog' )
       AND col.table_name = '<TableName>'
ORDER  BY col.column_name;  

Event Aggregator

Even though Event Aggregator could be termed as one of the lesser known patterns, the useful of the pattern cannot be ignored. In fact, it makes me wonder why it is lesser known.

Let us recap the observer pattern. One of the problems with observer pattern is that it could grow out of hand when the system has multiple event sources and multiple event subscribers. The Subscribers could themselves be source of some other events.

The Event Aggregator, as Martin Fowler mentions it, is a single source of truth – or rather in this case, single source of events indirection. It gathers events from multiple sources and propagate them to interested parties. The event aggregator is loosely coupled with both Observers and the Subjects, sitting in the middle of observers and publishers as a centralized message broker, allowing a single point of registration of events.

I have been using Caliburn Micro for my WPF applications for a while and it provides a quite useful implementation of Event Aggregator. Following section discusses a simplified version of Caliburn Micro’s implementation of Event Aggregator.

public interface IEventAggregator
{
    void Subscribe(object subscriber);
    void Unsubscribe(object subscriber);
    void PublishMessage(object message);
}

The Event Aggregator has three major methods exposed. One method each for Subscribing and Unsubscribing, and anther additional method for Subjects to publish events. The Subscribe() method could be defined as

private readonly List<WeakReference<Handler>> _handlers = new List<WeakReference<Handler>>();

public void Subscribe(object subscriber)
{
    lock (_handlers)
    {
        if (_handlers.Any(x => x == subscriber))
        {
            return;
        }

        _handlers.Add(new WeakReference<Handler>(new Handler(subscriber)));
    }
}

The Subscribe() method implementation is pretty straightforward. Each time it is invoked it would add the subscriber instance (passed as parameter) to a collection. The collection has been maintained as WeakReference – being a distant cousin of Observer pattern, the EventAggregator also inheritance some of the memory leak issues that is evident in Observer Pattern. The WeakReference allows us to workaround the problem to an extend.

As seen in the code above, the collection is of a type Handler (or rather WeakReference<Handler> to precise).The Handler Type maintains a reference to the subscriber along with a list of Message Types subscriber is interested in and the corresponding Event Handlers. We will look at the Handler definition before discussing further.

private class Handler
{
    private readonly object _subscriber;
    private Dictionary<Type, MethodInfo> _handlers = new Dictionary<Type, MethodInfo>();
    public Handler(object subscriber)
    {
        _subscriber = subscriber;

        var interfaces = _subscriber.GetType()
                                    .GetTypeInfo()
                                    .ImplementedInterfaces
                                    .Where(x => x.GetTypeInfo().IsGenericType && x.GetGenericTypeDefinition() == typeof(IHandleAsync<>));

        foreach (var @interface in interfaces)
        {
            var genericTypeArg = @interface.GetTypeInfo().GenericTypeArguments[0];
            var method = @interface.GetRuntimeMethod("HandleAsync", new[] { genericTypeArg });

            _handlers.Add(genericTypeArg, method);
        }

    }

    public object Subscriber => _subscriber;
    public void Handle(Type messageType, object message)
    {
        if (!_handlers.ContainsKey(messageType))
        {
            throw new Exception($"Message type {message} not registered");
        }

        var method = _handlers[messageType];
        method.Invoke(_subscriber, new[] { message });
    }
}


As you can observe in the code above, the Handler type uses reflection to iterate over the interfaces implemented by the subscriber. In particular, the Handler is interested in the generic interface IHandleAsync<>. Let us look at the interface first.

public interface IHandleAsync<T> where T : EventMessageBase
{
    Task HandleAsync(T message);
}

As seen in the code above, the interface has only a single method. HandleAsync<T>() which accepts a single parameter of Type T. This interface would be implemented by the subscribers who are interested in the publication of messages of type T.

Let us now look at the Unsubscribe method.

public void Unsubscribe(object subscriber)
{
    lock (_handlers)
    {
        WeakReference<Handler> toRemove = null;
        lock (_handlers)
        {

            foreach (var handler in _handlers)
            {
                if (handler.TryGetTarget(out var target))
                {
                    if (target.Subscriber == subscriber)
                        toRemove = handler;
                }
            }

            if(toRemove != null)
            {
                _handlers.Remove(toRemove);
            }
        }
    }
}

Not too much to explain there other than being conscience of thread safety. One another point to note in the Unsubscribe() method is that it removes any instances of Handler that has been reclaimed by the GC.

The last bit of code we need to look at in the implementation of EventAggregator is the PublishMessage() method.

public void PublishMessage(object message)
{
    if (message == null) throw new ArgumentNullException(nameof(message));

    var handlersToNotify = new List<Handler>();
    lock (_handlers)
    {

        foreach(var handler in _handlers)
        {
            if(handler.TryGetTarget(out var target))
            {
                handlersToNotify.Add(target);
            }
        }
    }

    foreach (var handler in handlersToNotify)
    {
        handler.Handle(message.GetType(), message);
    }

}

The core functionality of the PublishMessage() method is to accept a message and iterate over the active Subscribers. It would then inturn Handler instance to check the internal dictionary of the instance has subscribed for the message of type which was accepted as parameter.This is accomplished using the Handler.Handle() method. It would retrieve the event handlers associated and invoke them as seen the code below (implementation of the Handler.Handle() which we had already seen above)

public void Handle(Type messageType, object message)
{
    if (!_handlers.ContainsKey(messageType))
    {
        throw new Exception($"Message type {message} not registered");
    }

    var method = _handlers[messageType];
    method.Invoke(_subscriber, new[] { message });
}

That would complete our EventAggregator. Now it is time to see EventAggregator in action and how the subscriber subscribles themselves.

public class SubscriberAlpha:IHandleAsync<UserSaysHelloMessage>
{
    public SubscriberAlpha(IEventAggregator eventAggregator)
    {
        eventAggregator.Subscribe(this);
    }

    public Task HandleAsync(UserSaysHelloMessage message)
    {
        Console.WriteLine($"Message : {message.Message}");
        return Task.CompletedTask;
    }

}

As seen in the code above, the subscriber has done couple of things here. First, it has implemented the IHandleAsync<> interface with the generic parameter UserSaysHelloMessage.The generic parameter type, in this case UserSaysHelloMessage is the type of the message which this particular subscriber is interested in.

It also uses the instance of IEventAggregator to subscribe to the centerlized EventAggregator. The HandleMessageAsync(UserSaysHelloMessage msg) method would be called by the Event Aggregator when any publisher publishes a message of the same type.

Let us write some client code to see how our little Event Aggregator example works.

var eventAggregator = new EventAggregator();
var subscriber = new SubscriberAlpha(eventAggregator);
var publisher = new PublisherAlpha(eventAggregator);

publisher.PublishMessage("John says hello");

eventAggregator.Unsubscribe(subscriber);

publisher.PublishMessage("John says hello");

Where the PublisherAlpha is defined as

public class PublisherAlpha
{
    private IEventAggregator _aggregator;
    public PublisherAlpha(IEventAggregator eventAggregator)
    {
        _aggregator = eventAggregator;
    }

    public void PublishMessage(string message)
    {
        _aggregator.PublishMessage(new UserSaysHelloMessage(this,message));
    }
}

As expected our output would contain only a single Message.

Message : John says hello

By the time the publisher sends the second message, the subscriber has already unsubscribed from the central message broker. Hence, the second message would not be notified to the subscriber.

While I liked the implementation of Event Aggregator by Caliburn Micro, one part which I would like to tweak around would be have the subscriber the ability to subscribe/unsubscribe individual message types in the runtime. In the next blog post, we will look into another example of Event aggregator implementation, which would address this problem (or rather wish).

If you would like to have a look at the complete code sample shown here, you can access it here in my github.

Cheat Code for Database Meta information : Sql Server

This post acts as a quick reference/Cheat code for anyone who would like to query the meta information about different entities in a database using Sql Server.

Get all Views in the Database

SELECT NAME,
       Object_definition (Object_id(NAME))
FROM   sys.views  

Get All Tables in the Database

SELECT NAME
FROM   sys.tables  

Get all columns from a table

SELECT c.NAME,
       c.max_length,
       c.is_nullable,
       c.is_identity,
       t.NAME AS DbType
FROM   sys.columns AS c
       INNER JOIN sys.types AS t
               ON c.user_type_id = t.user_type_id
       LEFT OUTER JOIN sys.default_constraints AS d
                    ON c.default_object_id = d.object_id
WHERE ( c.object_id = Object_id('<TableName>') )

Get All Indices from database

 SELECT t.NAME               AS ParentTable,
       ind.NAME,
       col.NAME             AS ColumnName,
       ind.type_desc        AS Type,
       ic.is_descending_key AS IsDescending,
       ind.is_unique,
       ind.index_id
FROM   sys.indexes ind
       INNER JOIN sys.index_columns ic
               ON ind.object_id = ic.object_id
                  AND ind.index_id = ic.index_id
       INNER JOIN sys.columns col
               ON ic.object_id = col.object_id
                  AND ic.column_id = col.column_id
       INNER JOIN sys.tables t
               ON ind.object_id = t.object_id
WHERE  ind.is_primary_key = 0
       AND ind.is_unique_constraint = 0
ORDER  BY ind.index_id  

Get All Primary Key Constraints

 SELECT TC.table_name,
       TC.constraint_name,
       CCU.column_name AS ColumnName
FROM   information_schema.table_constraints AS TC
       JOIN information_schema.constraint_column_usage AS CCU
         ON TC.constraint_name = CCU.constraint_name
WHERE  TC.table_name = '<TableName>'
       AND TC.constraint_type = 'PRIMARY KEY'  

Get all Unique Key Constraints

select TC.TABLE_NAME, 
                TC.CONSTRAINT_NAME,
                CCU.COLUMN_NAME as ColumnName
                from INFORMATION_SCHEMA.TABLE_CONSTRAINTS as TC   
                Join INFORMATION_SCHEMA.CONSTRAINT_COLUMN_USAGE as CCU On TC.CONSTRAINT_NAME = CCU.CONSTRAINT_NAME
                where TC.TABLE_NAME = '<TableName>' and TC.CONSTRAINT_TYPE = 'UNIQUE'

Get all Check Constraints

select TC.TABLE_NAME, 
                   TC.CONSTRAINT_NAME ,
                   CCU.COLUMN_NAME as ColumnName ,
                   CC.CHECK_CLAUSE 
                   from INFORMATION_SCHEMA.TABLE_CONSTRAINTS as TC   
                    Join INFORMATION_SCHEMA.CONSTRAINT_COLUMN_USAGE as CCU On  TC.CONSTRAINT_NAME = CCU.CONSTRAINT_NAME 
                    Join INFORMATION_SCHEMA.check_constraints as CC On CC.CONSTRAINT_NAME = TC.CONSTRAINT_NAME
                    where TC.TABLE_NAME = '<TableName>' and TC.CONSTRAINT_TYPE = 'CHECK'

Get all Foreign Key Constraints

 SELECT RC.constraint_name,
       KF.table_name  AS TableName,
       KF.column_name AS ColumnName,
       KP.table_name  AS ReferenceTable,
       KP.column_name AS ReferenceColumn
FROM   information_schema.referential_constraints RC
       JOIN information_schema.key_column_usage KF
         ON RC.constraint_name = KF.constraint_name
       JOIN information_schema.key_column_usage KP
         ON RC.unique_constraint_name = KP.constraint_name
WHERE  KF.table_name = '<TableName>'  

Get all Default value Constraints

 SELECT con.[name],
       col.[name] AS ColumnName,
       con.[definition],
       ty.NAME    AS DbType
FROM   sys.default_constraints con
       LEFT OUTER JOIN sys.objects t
                    ON con.parent_object_id = t.object_id
       LEFT OUTER JOIN sys.all_columns col
                    ON con.parent_column_id = col.column_id
                       AND con.parent_object_id = col.object_id
       INNER JOIN sys.types AS ty
               ON col.user_type_id = ty.user_type_id
WHERE  t.NAME = '<TableName>'
ORDER  BY con.NAME  

That’s it from Sql Server. We will attempt to retrieve the same set of information from other Db sources as well in future posts.

Gof : Observer Pattern

This has been a long overdue. I had started with this series of byte sized tutorials on various patterns but never went ahead and completed the series. So here am continuing from where I left with the Observer Pattern.

While working with applications, there would times you could have an object which would like to notify other interested object about a change in its state. The interested subscribers could have been implemented in such a way that it sends indefinete amount of request asking the subject if it has changed. But that would not be ideal. Instead, you would want the subject to notify the subscribers every time the state change occurs, thereby avoid the need for the innumerous ‘Is there a state change’ calls.

Imagine how subscribers subscribe to newspaper. As a consumer, one would subscribe a particular newspaper publisher and would be delivered the print each time there is a new one out there. What you do with you print and how you makes use of it is upon the each subscriber, but one thing is common – if you are subscribed to the publisher, you would be notified and given your copy when a new one is out.

This is the princple on which observer pattern works. It ensure an implementation where subscribers and observers can remain loosely coupled while providing the subject the ability to notify the subscribers of state changes.

Let us first have a look at the class diagram and overall summary of the observer pattern.

The core participants of the observer pattern are

  • ISubject
  • ConcreteSubject
  • IObserver
  • ConcreteObservers

The abstract Subject contains methods which can be used by observers to register/unregister themselves. The subject on other hand, maintains a collection of all the observers who have registered themselves with it. It would then use the Update method (part of IObserver) of the observers to notify them of a state change. Let us go ahead and implement the abstract and concrete observers.

// Abstract Subsccriber
public abstract class SubscriberBase
{
    protected readonly INewsPublisher _newsPublisher;
    protected WeakReference<SubscriberBase> _weakReference;
    public SubscriberBase(INewsPublisher publisher)
    {
        _newsPublisher = publisher;
    }
    public abstract void Update(string message);

    public void Subscribe()
    {
        _weakReference= _newsPublisher.Register(this);
    }

    public void Unsubscribe()
    {
        _newsPublisher.Unregister(_weakReference);
    }
}

And now for concrete subscribers.

public class AlphaSubscriber : SubscriberBase
{
    public Guid Id { get; set; }
    public AlphaSubscriber(Guid id, INewsPublisher publisher):base(publisher)
    {
        Id = id;
    }
    public override void Update(string message)
    {
        Console.WriteLine($"{nameof(AlphaSubscriber)}-{Id} has recieved the message {message}");
    }
}

public class BetaSubscriber : SubscriberBase
{
    public int Id { get; set; }
    public BetaSubscriber(int id, INewsPublisher publisher):base(publisher)
    {
        Id = id;
    }
    public override void Update(string message)
    {
        Console.WriteLine($"{nameof(BetaSubscriber)}-{Id} has recieved the message {message}");
    }
}

Notice how the subscribers “Has-A” instance of subject. This allows it too unsubscribe themselves.

Let us now implement the abstract and concrete subjects.

public interface INewsPublisher
{
    WeakReference<SubscriberBase> Register(SubscriberBase subscriber);
    void Unregister(WeakReference<SubscriberBase> subscriber);
    void Publish(string message);
    void AddNews(string news);
}

public class NewsPublisherConcrete : INewsPublisher
{
    public List<WeakReference<SubscriberBase>> _SubscribersCollection = new List<WeakReference<SubscriberBase>>();
    public void AddNews(string news)
    {
        Publish(news);
    }

    public void Publish(string message)
    {
        foreach(var weakReference in _SubscribersCollection)
        {
            if(weakReference.TryGetTarget(out var subscriber))
            {
                subscriber.Update(message);
            }
            else
            {
                _SubscribersCollection.Remove(weakReference);
            }
        }
    }

    public WeakReference<SubscriberBase> Register(SubscriberBase subscriber)
    {
        var weakReference = new WeakReference<SubscriberBase>(subscriber);
        _SubscribersCollection.Add(weakReference);
        return weakReference;
    }

    public void Unregister(WeakReference<SubscriberBase> subscriber)
    {
        _SubscribersCollection.Remove(subscriber);
    }
}

Notice how I have used weak references. This is a protection against memory leaks which may occur in the observer pattern. Every time the client adds a “news” item via the AddNews() method, the Subject would notify the clients iterating over the the references which it has build and calling the Update method of each interested(subscribed) observer. Let us now write client code to complete the example.

var publisher = new NewsPublisherConcrete();

var alphaSubscribers = Enumerable.Range(1,5).Select(x => new AlphaSubscriber(Guid.NewGuid(),publisher)).ToList();
var betaSubscribers = Enumerable.Range(1,3).Select(x => new BetaSubscriber(x,publisher)).ToList();

alphaSubscribers.ForEach(x => x.Subscribe());
betaSubscribers.ForEach(x => x.Subscribe());

Console.WriteLine("Adding message to News");
publisher.AddNews("Hello World");

alphaSubscribers.ForEach(x => x.Unsubscribe());
betaSubscribers.First(x => x.Id == 2).Unsubscribe();
Console.WriteLine("Adding another message to News");
publisher.AddNews("Another Hello World");

That’s all the Observer pattern is all about. In the next part, we will explore the EventAggregator Pattern, a variant of Observer. The complete code samples could be found in my github.

Retrieve DataPoints displayed using Oxyplot when Zooming or Panning

One of questions I recently saw in Stackoverflow involved Oxyplot. User wanted to obtain the points which are currently displayed on screen. Remember, like with most graph controls, User could zoom/pan with Oxyplot and the points which are currently visible could only be a subset of actual points in the series.

This could be achieved by retrieving the currently displayed part of graph(ScreenRectangle) with GetScreenRectangle and verifying if each of points would fall in it.

var series = plotModel.Series.OfType<OxyPlot.Series.LineSeries>().Single();
var pointCurrentlyInDisplay = new List<DataPoint>();
foreach (var point in series.ItemsSource.OfType<DataPoint>())
{
    if (series.GetScreenRectangle().Contains(series.Transform(point)))
    {
        pointCurrentlyInDisplay.Add(point);
    }
}

An important point to observe in above code is how we transform the existing DataPoint to ScreenPoint using the Transform()method.

Do note that if you had assigned the points via Series.Points.AddRange() instead of Series.ItemSource, you could have to retrieve the existing points using

series.Points.OfType<DataPoint>()

That would retrieve you the points which are currently on display in the graph owing to Zooming or Panning.

More on debugging DependencyProperty

In the previous post on DependencyPropertyHelper, we explored one way of debugging the Dependency Properties.

The DepedencyPropertyHelper provides you details on from which value provider the final value was calculated from. However, if you want to trace and ensure the binding has been set correctly, you could make use of PresentationTraceSources.

For example, consider following binding.

<Button Content="{Binding ButtonTitle}"/>

To enable tracing, one could enable the PresentationTraceSources as,

<Button Content="{Binding ButtonTitle, diag:PresentationTraceSources.TraceLevel=High}"/>

Do not forget to add reference to System.Diagnostics

xmlns:diag="clr-namespace:System.Diagnostics;assembly=WindowsBase"

Now your output window would have the entire trace.

System.Windows.Data Warning: 60 : BindingExpression (hash=28316044): Default mode resolved to OneWay
System.Windows.Data Warning: 61 : BindingExpression (hash=28316044): Default update trigger resolved to PropertyChanged
System.Windows.Data Warning: 62 : BindingExpression (hash=28316044): Attach to System.Windows.Controls.Button.Content (hash=17324607)
System.Windows.Data Warning: 67 : BindingExpression (hash=28316044): Resolving source 
System.Windows.Data Warning: 70 : BindingExpression (hash=28316044): Found data context element: Button (hash=17324607) (OK)
System.Windows.Data Warning: 71 : BindingExpression (hash=28316044): DataContext is null
System.Windows.Data Warning: 65 : BindingExpression (hash=28316044): Resolve source deferred
System.Windows.Data Warning: 67 : BindingExpression (hash=28316044): Resolving source 
System.Windows.Data Warning: 70 : BindingExpression (hash=28316044): Found data context element: Button (hash=17324607) (OK)
System.Windows.Data Warning: 78 : BindingExpression (hash=28316044): Activate with root item ShellViewModel (hash=18700393)
System.Windows.Data Warning: 108 : BindingExpression (hash=28316044):   At level 0 - for ShellViewModel.ButtonTitle found accessor RuntimePropertyInfo(ButtonTitle)
System.Windows.Data Warning: 104 : BindingExpression (hash=28316044): Replace item at level 0 with ShellViewModel (hash=18700393), using accessor RuntimePropertyInfo(ButtonTitle)
System.Windows.Data Warning: 101 : BindingExpression (hash=28316044): GetValue at level 0 from ShellViewModel (hash=18700393) using RuntimePropertyInfo(ButtonTitle): 'Proceed'
System.Windows.Data Warning: 80 : BindingExpression (hash=28316044): TransferValue - got raw value 'Proceed'
System.Windows.Data Warning: 89 : BindingExpression (hash=28316044): TransferValue - using final value 'Proceed'

You could also set write custom TraceListener to break at the binding error. For example,

PresentationTraceSources.Refresh();
PresentationTraceSources.DataBindingSource.Listeners.Add(new ConsoleTraceListener());
PresentationTraceSources.DataBindingSource.Listeners.Add(new DebugTraceListener());
PresentationTraceSources.DataBindingSource.Switch.Level = SourceLevels.Error;

Where DebugTraceListener is defined as

public class DebugTraceListener : TraceListener
{
    public override void Write(string message)
    {
    }

    public override void WriteLine(string message)
    {
        Debugger.Break();
    }
}

This would ensure a break point is hit whenever encountered with a missing binding.

.Net 6: Linq enhancements

Linq has got some noticeably enhancements in the .Net 6. In this post, we will briefly visit some of them.

Specify Default Value for FirstOrDefault, LastOrDefault, SingleOrDefault

One of the features I am so relieved to see if the support for specifying default value for FirstOrDefault()LastOrDefault(), and SingleOrDefault(). I never quite understood why it wasn’t included in the first place. Previously the mentioned methods would return default(T) if the source return empty. With .Net 6, you could specify the default value which needs to be returned instead of default(t). For example

var data = GetData(10);

// Prior to .Net 6
var firstOrDefault = data.Where(x => x.Id > 100).DefaultIfEmpty(new User(-1, "GhostUser")).First();
var lastOrDefault = data.Where(x => x.Id > 100).DefaultIfEmpty(new User(-1, "GhostUser")).Last();
var singleOrDefault = data.Where(x => x.Id > 100).DefaultIfEmpty(new User(-1, "GhostUser")).Single();


// With .Net
var firstOrDefault = data.FirstOrDefault(x => x.Id > 100, new User(-1, "GhostUser"));
var lastOrDefault = data.LastOrDefault(x => x.Id > 100, new User(-1, "GhostUser"));
var singleOrDefault = data.SingleOrDefault(x => x.Id > 100, new User(-1, "GhostUser"));

The improvement is quite easy to see. The code has become more cleaner and verbose.

KeySelector for ExceptBy/ IntersectBy/ DistinctBy/ UnionBy/ MaxBy/ MinBy

Previously, if you needed to get the Max using a property using Linq methods, it was painful to say the least

var max = data.OrderByDescending(x => x.Id).First();

Things get even more ugly when we attempt Except(),Intersect(),Distinct() and Union() by a property. MoreLinq library had few methods which helped us in this regard, but with the inbuild Linq methods, this was still unavailable, until .Net 6.

The methods Except,Intersect, Distinct, Union, Max, and Min have got a variant which would now receive a key selector (Func<T,TKey>). Here is a short sample

demoCollection.ExceptBy(secondCollection.Select(x=>x.Name),user=>user.Name);
demoCollection.IntersectBy(secondCollection.Select(x => x.Name), user => user.Name);
demoCollection.DistinctBy(user=>user.Name);
demoCollection.UnionBy(secondCollection,user=>user.Name).;
demoCollection.MaxBy(user=>user.Id);
demoCollection.MinBy(user=>user.Id);

Range for Take

Range was introduced in C# 8. .Net 6 now adds an override to the Take() method which would accept a Range. For example,

demoCollection.Take(10..^10);

Chunk

Third Party Linq add-on libraries had this functionality for a long time now, but Microsoft decided to add chunk to its own set of extension methods of IEnumerable with .Net 6. Chunk allows you to process large collection of data in batches. For example, the following method call would split the demoCollection into chunks of 5, so that you could process them as batches.

demoCollection.Chunk(5);

Zip with IEnumerables

Linq methods previously allowed developers to merge an element in the first collection with an element in the second collection using the Zip method.Previously, if you need to Zip 3 collection, you would need to opt for a solution that might look like following.

int[] numbers = { 1, 2, 3, 4 };
string[] words = { "one", "two", "three" };
string[] romans = { "I", "II", "III" };

var numbersAndWords = numbers.Zip(words, (number, word) => (number, word));
var numbersAndWordsAndRoman = numbersAndWords.Zip(romans,(numberWord,roman)=> (numberWord.number, numberWord.word,roman));

foreach (var (number, word, roman) in numbersAndWordsAndRoman)
    WriteLine($"{number}-{word}-{roman}");

The new improvements now allows you to include 3 collections in your operation.

int[] numbers = { 1, 2, 3, 4 };
string[] words = { "one", "two", "three" };
string[] romans = { "I", "II", "III" };

var numbersAndWords = numbers.Zip(words,romans);

foreach (var (number,word,roman) in numbersAndWords)
    WriteLine($"{number}-{word}-{roman}");

That definitely has got a lot more cleaner.

TryGetNonEnumeratedCount

There are times when you would like to declare explicitly the capacity of the collection. This is quite useful when you do not want the capacity to double each time count exceeds capacity (not to mention all the copy operations involved). The TryGetNonEnumeratedCount method attempts to obtain the count of the source enumerable without forcing an enumeration. If it doesn’t find a property (say Count from ICollection) then it would return 0;

demoCollection.TryGetNonEnumeratedCount(out var enumCount); 

Those are some of the improvements in .Net 6 for Linq. We will continue exploring the .Net 6 features in the blogs to come. For the complete source of the code in the post, please use my Github.

DependencyPropertyHelper.GetValueSource : Debugging Helper for Dependency Properties

DependencyPropertyHelper.GetValueSource is a great debugging aid in detecting the source of value of a Dependency Property. This is quite useful for WPF developers who might need to figure out the source which provides the current value for the Dependency Property.

The DependencyPropertyHelper.GetValueSource returns a structure ValueSource which has 5 Properties.

  • BaseValueSource
  • IsAnimated
  • IsCoerced
  • IsCurrent
  • IsExpression
DependencyPropertyHelper.GetValueSource(buttonControl,CustomValueProperty)
{System.Windows.ValueSource}
    BaseValueSource: Local
    IsAnimated: false
    IsCoerced: false
    IsCurrent: false
    IsExpression: true

Dependency Property Value Precedence

The value of Dependency Property is calculated in 5 Steps.

  • Calculate the Base Value
  • Evaluate Expression if any
  • Apply Animation if any
  • Coerce Value

The BaseValueSource in the ValueSource structure speficies how the Base Value of the Dependency property is calculated. The base value of Dependency Property is calculated with aid of property value providers. Some ofthe Value Providers in decreasing Order of precedence are

  • Local Value
  • Templated Parent
  • Implicit style
  • Style triggers
  • Template Triggers
  • Style Setters
  • Theme
  • Inheritence
  • Default Value

Once the base value has been determined, the value is then passed through a series of steps depending on how the value is configured. These include Expressions, Animations and coerce callbacks if they are configured. You can follow more details on Dependency Property Value Precedence in the MSDN documentation

The DependencyPropertyHelper.GetValueSource provides an indication on how the current value in Dependency Property has been determined.