Category Archives: ASP.NET Core

Dependency Validation Diagrams do not work in ASP.NET Core / .NET Core

Introduction

Dependency validation helps to keep the code architecture clean and rules enforced. The video below gives a quick introduction to the dependency validation in Visual Studio.

Recently a friend, asked about enforcing constraints in a project architecture, I explained this to him. But I haven’t used it any of my previous projects (we’re good developers who do not spoil the code :P) , so thought of giving it a try. As shown in the video things should be straight forward but I ended up my validations never kicked in.

With some investigation, I found that when we add the DV project to the solution it adds the following package to all the projects.

Microsoft.DependencyValidation.Analyzers

If your project is made out from a .net core / asp.net core project template then it fails to install the above NuGet package and obviously the validation does not work.

How to fix this ?

I created a ASP.NET Core project based on .NET Framework (same applies to .NET Core as well). Added some class libraries and draw a following dependency validation layered diagram.

Layered Diagram

Red one is the web project (asp.net core) and others are simple class libraries. The structure is not complex. Just to check the validation, I referenced the DataContext in the web project as below.


public void ConfigureServices(IServiceCollection services)
{
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
// This is right
services.AddSingleton<IProductService, ProductService>();
// this is wrong and DV should fail
services.AddSingleton<IMyDbContext, MyDbContext>();
}

But the validation never fired.

In order to do get this work.

  • Install the following NuGet in the ASP.NET Core / .NET Core template based projects in the solution. Other projects have it installed automatically when we add the DV project.
Install-Package Microsoft.DependencyValidation.Analyzers -Version 0.9.0
  • Open the ASP.NET Core template project file. Add the following. line numbers 15-18 should be manually added to include the DV diagram in the asp.net core web project.


<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFramework>net471</TargetFramework>
</PropertyGroup>
<ItemGroup>
<Folder Include="wwwroot\" />
</ItemGroup>
<ItemGroup>
….
<PackageReference Include="Microsoft.DependencyValidation.Analyzers" Version="0.9.0" />
<AdditionalFiles Include="..\DependencyValidation\DependencyValidation.layerdiagram">
<Link>DependencyValidation.layerdiagram</Link>
<Visible>True</Visible>
</AdditionalFiles>
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\LayeredProject.DataContext\LayeredProject.DataContext.csproj" />
<ProjectReference Include="..\LayeredProject.Services\LayeredProject.Services.csproj" />
</ItemGroup>
</Project>

After this all set with one small problem. Now, when we build the project, the validation kicks and the build will fail.

But the error response from Visual Studio is not consistence. It will always fail the build – that’s 100% expected behavior and it is right. But sometimes the error only appears in the Output window and not in the Error List. Also, sometimes the red squiggly does not appear.

This happens because the ASP.NET Core / .NET Core project templates do not support the DV, we did a workaround to make it work and it has some links broken to display the error message in the Error List, I hope soon Microsoft will add support to the DV in ASP.NET Core and .NET Core based project templates.

You can check  / reproduce this, using the following two branches. The ‘normal’ branch has problem and the ‘solved’ branch is patch applied.

https://github.com/thuru/aspnetcore-dv/tree/normal

https://github.com/thuru/aspnetcore-dv/tree/solved

Used tooling

  • VS 2017 Enterprise (15.7.4)
  • ASP.NET Core 2.1
  • .NET Framework 4.7.1

 

ASP.NET Core Dependency Injection

Introduction

ASP.NET Core comes with an inbuilt Dependency Injection (DI) module. We can register custom DI modules as well. This post explains the fundamentals of the inbuilt DI module available in the ASP.NET Core.

Exploring deeper into the Service Registrations

Get the Code for the below experiment from my GitHib

ASP.NET Core provides 3 generic service registration types for custom services.

  • Singleton – One instance of the dependency to serve across all the requests.
  • Transient – Different instances for each dependent call, thus creating different instances of the injected service in a single request call flow.
  • Scoped – Single instance of the dependency in a single call flow. Within the single request call one same instance will be used.

Apart from the above 3 generic service registrations ASP.NET Core provides other inbuilt service registration methods.  Let’ see how the these three generic service registration types work and how the lifecycle of the instances are handled.

 

Let’s have one common interface IMyService and create 3 different types of interfaces from the common type interface, each for the different service type registrations.


public interface IMyService
{ 
Guid Id { get; set; }
}

public interface IMySingeltonService : IMyService
{
}

public interface IMyTransientService : IMyService
{
}

public interface IMyScopedService : IMyService
{
}

Then let’s implement the above interfaces with three different classes. All these classes will create a new Guid in the constructor.


public class MySingletonService : IMySingeltonService
{
public Guid Id { get; set; }

public MySingletonService()
{
Id = Guid.NewGuid();
}
}

public class MyTransientService : IMyTransientService
{
public Guid Id { get; set; }

public MyTransientService()
{
Id = Guid.NewGuid();
}
}

public class MyScopedService : IMyScopedService
{
public Guid Id { get; set; }

public MyScopedService()
{
Id = Guid.NewGuid();
}
}

In the constructors of the implemenations we generate a Guid and we’ll print this in the View to see how many times the service instances are being instantiated. In ordert to do that let’s register the services with the right generic service registration type method respective to their implmentation name. (the generics syntax < > is not getting formatted with the wordpress code tag so I pasted the image for the below snippet. )

 

blog code 1

We can inject the services into the HomeController with the following constructir and will print the Id of each service in the View.


private readonly IMySingeltonService _singletonService;
private readonly IMyTransientService _transientService;
private readonly IMyScopedService _scopedService;

public HomeController(IMySingeltonService singletonService, IMyTransientService transientService, 
 IMyScopedService scopedService)
 {
 _singletonService = singletonService;
 _transientService = transientService;
 _scopedService = scopedService;
 }

public IActionResult Index()
 {
 ViewBag.Singleton = _singletonService.Id;
 ViewBag.Transient = _transientService.Id;
 ViewBag.Scoped = _scopedService.Id;

return View(ViewBag);
 }

When we run the application we will get the  below results. 2 different requests are compared.

blog 2

You can note, the Singleton implementation is same across different requests. Only one instance of service which is registered as Singleton available across the requests.

The above implementation does not give a full picture to compare the difference between Transient and Scoped service registrations as they both have difference instances in different requests. In order to understand the behavior of them we need to implement another service.


public interface IMyAnotherService
{
Guid SingletonId { get; set; }
Guid TransientId { get; set; }
Guid ScopedId { get; set; }

}

public class MyAnotherService : IMyAnotherService
{
private readonly IMySingeltonService _singletonService;
private readonly IMyTransientService _transientService;
private readonly IMyScopedService _scopedService;

public Guid SingletonId { get; set; }
public Guid TransientId { get; set; }
public Guid ScopedId { get; set; }

public MyAnotherService(IMySingeltonService singletom, IMyTransientService transient, IMyScopedService scoped)
{
_singletonService = singletom;
_transientService = transient;
_scopedService = scoped;

SingletonId = singletom.Id;
TransientId = transient.Id;
ScopedId = scoped.Id;
}
}

 

Do the requried changes in the Controller to accpet IMyAnotherService.


private readonly IMySingeltonService _singletonService;
private readonly IMyTransientService _transientService;
private readonly IMyScopedService _scopedService;
private readonly IMyAnotherService _anotherService;

public HomeController(IMySingeltonService singletonService, IMyTransientService transientService,
IMyScopedService scopedService, IMyAnotherService anotherService)
{
_singletonService = singletonService;
_transientService = transientService;
_scopedService = scopedService;
_anotherService = anotherService;
}

public IActionResult Index()
{
ViewBag.Singleton = _singletonService.Id;
ViewBag.Transient = _transientService.Id;
ViewBag.Scoped = _scopedService.Id;

ViewBag.AnotherSingleton = _anotherService.SingletonId;
ViewBag.AnotherTransient = _anotherService.TransientId;
ViewBag.AnotherScoped = _anotherService.ScopedId;

return View(ViewBag);
}

Now we can register the IMyAnother service in different modes and check the instance ouptuts. The below figure explains the instance lifetime. For the same instance the similar color is maintained.

blog 4

In a simpler form we summarize this like below. How many times a construcotr is being called.

  • Singleton – Once in the application lifetime.
  • Transient – Everytime the instance is requested regardless of the request.
  • Scoped – Once per request regardless of how many services use it.

DI figure

When IMyAnohterService is added as a Scoped service the below image shows two different requests.

Singleton service remains same across all the requests.

Transient service changes between HomeController and IMyAnotherService within the same request.

Scoped service does not change in the same request as it’s the same instance for both the HomeController and IMyAnotherService but between requests it changes.

 

blog 5

Interesting Scenrio IHttpContextAccessor 

In ASP.NET Core DI model the framework also provides some additional injection methods for some known scenarios. Like registering EF DbContext using the AddDbContext method. This method by default injects the DbContext in the Scoped mode.

But the interesting scenario is registering IHttpContextAccessor as Singleton as shown below.

blog 6

This service is used to access the HttpContext of the request, so registering this service as Singleton based on the official documentation collides with the experiement we did above, because having the Singleton registration would not give the flexibility to get the HttpContext per request.

But the framework handles it and this is explained well in this blog post

Conclusion

We have the understanding of the DI in ASP.NET Core and some special in built framework DI methods.

In the business logic services it’s good we add them as Scoped, unless we have a generic implementation of some functions like email.

Azure Elastic Pool and EF Core Architecture and Developer Workflow

Introduction to the Azure Elastic Pools and Elastic Jobs

Azure Elastic Database Pool is a service which helps to share the database resources (DTUs) and the management of many databases easy. This is the tool, for solutions which follow the dedicated database tenant isolation strategy. Because apart from the resource elasticity between the database Elastic Pools have Elastic Jobs which is a separate configuration, which allows to manage the databases from a single interface.

Having different databases for different tenants or for any other isolations, comes with the concern of a shared index of those databases. Application get to know which database to connect from this shared index. Often this index is known as master database.

There can be situations where master database is not required in determining which database to connect when application get this information from some other sources like from a cache or from configurations or from request claims and etc.

Azure Elastic Pool has a tool known as Shared Map Manager (which is the master database), this Shared Map Manager works along with the Elastic Client Library. Elastic Client Library has a good support with the Entity Framework.

When it comes to EF Core, the support of the Elastic Client Library seems not actively available, and EF Core has its own differences compared to Entity Framework as well. This blog post addresses these issues.

Architecture Pattern for using Elastic Database Pool with EF Core

Assume we have a multiple tenants with different dedicated databases and they are configured in a pool. Also we have the Elastic Jobs configured in the subscription. (A subscription can have only one Elastic Jobs interface and multiple pools can use the same interface) Read more about Elastic Jobs and how to configure them

The below figure shows the architecture model for the Azure Elastic Pool development.

Elastic Database Pool Architecture

The below points summarize the idea.

  1. Developer generates the code first migrations from his IDE (typically this is VS PMC) pointing to the Developer Db.
  2. Developer Db can be any valid SQL instance – either an Azure SQL instance or a in the developer machine.
  3. EF Core DbContext parameter-less constructor should point to the Developer Db.
  4. In the pool apart from the tenant databases, create a database which holds only the schema – this database is known as Zero Db
  5. Zero Db will be used to generate the delta of the schema. Developers can use VS Database Project to generate the TSQL of delta.
  6. The generated delta script will be executed using the Elastic Jobs interface either by any sort of automation or using the Azure portal itself.

 

Developers can generate the scripts without having the Zero database, using the EF Core commands, but I highly recommend to have a schema only database in the pool, because of the following reasons.

  1. Zero Db can be used to generate the delta TSQL
  2. At any given point we have the schema only version of the production schema
  3. Creating a new tenant database is easy at any point as we can simply copy the Zero Db

Implementation

In order to operate an enterprise scale solution, addition to the working code the entire flow of the development and deployment should be in place.

In order to make the developer migrations work as seamless with the existing VS PMC based experience and also to trigger the right database connection for the right tenant, we need an implementation of DbContext in the following way.


public class MassRoverContext : DbContext
{
public MassRoverContext()
{
}

public MassRoverContext(DbContextOptionsBuilder optionsBuilder)
{
base.OnConfiguring(optionsBuilder);
}

protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
{
if (optionsBuilder.IsConfigured == false)
{
optionsBuilder.UseSqlServer("");
}
base.OnConfiguring(optionsBuilder);
}
}

public DbSet RoverEquipment { get; set; }
}

The parameter-less constructor of the DbContext will be used in the migrations.

The constructor takes a DbContextOptionsBuilder<MassRoverContext> will be used in the applications which points to the right database determined by some logic in the application.

The below code snippet shows a common service which determines the correct DbContext for the application in ASP.NET Core


public class ContextService : IContextService
{
private readonly HttpContext _httpContext;
private readonly ConnectionSettings _connectionSettings;

public ContextService(IHttpContextAccessor httpContentAccessor, IOptions settings)
{
_httpContext = httpContentAccessor.HttpContext;
_connectionSettings = settings.Value;
}

public MassRoverContext MassRoverContext
{
get
{

var sqlConnectionBuilder = new SqlConnectionStringBuilder(_connectionSettings.ZeroDbConnectionString);

// determine the mapping based on some value. In this sample the database mapping is determined by a header value tenantid
sqlConnectionBuilder.Remove("Database");
sqlConnectionBuilder.Add("Database", _httpContext.Request.Headers["tenantid"].ToString());

var dbOptionsBuidler = new DbContextOptionsBuilder();
dbOptionsBuidler.UseSqlServer(sqlConnectionBuilder.ConnectionString);

return new MassRoverContext(dbOptionsBuidler);
}
}
}

Notes:

The shared index data source which holds the mapping of the tenant and the database is not shown in the above figure, since this shared index can be anything. In our example for the simplicity, assume the tenant id is in the request claim and this claim holds the name of the database. This SHOULD NOT BE USED IN PRODUCTION

The registration of the services is not included in this post, since posting the entire flow of how EF Core project and ASP.NET Core project connects is outside the scope of this article. But the full code is available in this repo.

Continuous Deployment & Automation

In this section let’s discover how the continuous deployment can be performed. We have the delta TSQL generated either by comparing the schema between the Developer Db and Zero Db or by any other mechanism.

Now we should prepare an automation script or a running code to submit the delta TSQL to the Elastic Jobs interface. Elastic Job will run the job across the databases in the pool.

I created a simple console application which submits the task to the Elastic Jobs interface. Access the code from this repo

The Elastic Jobs SDK is still in preview of the time of this writing and I will be conintously updating this cosole application and will post a seperate blog on how to plug this with VSTS Build and Release Definitions.

 

 

 

Using Akka.NET with ASP.NET Core – Creating a Quiz API

This is a template and quick start guide for Akka.NET with ASP.NET Core. You can grab the concepts of using Akka.NET with ASP.NET Core and how Akka.NET actor model can be used in a simple quiz or survey based scenario.

But at the same time, this post will not provide all the fundamentals of actor model programming or Akka.NET. It assumes that you already have the understanding of the actor model and reactive programming basics, along with the some practical experience with the concepts of Akka.NET.

Scenario :  A quiz engine has many quizzes and users can attend the quizzes. Each user can attend many quizzes as possible at the same time. So each user session is associated with a quiz. One user can have many quiz sessions at the same time. A simplest session key is a combination of quiz Id and user Id. This combination is unique and referred as a session Id. Each session is an actor.

Also a template actor provides the quiz templates during the session creation. Each session actor gets the fresh copy of the quiz during session creation.

The below diagram shows the actor system used in this scenario.

Akka.NET actor model for quiz engine

Step by step explanation

  • In the ASP.NET Core Startup class the actor system (QuizActorSystem) is instantiated.
  • QuizMasterActor is created in the context of QuizActorSystem and the QuizActorSystem is added to the ASP.NET Core services collection, to be consumed by the controllers.
  • QuizMasterActor creates QuizSessionCoordinatorActor and QuizTemplateActor under its context.
  • For simplicity the QuizController of ASP.NET Core has two actions.
    1. GetQuestion – This gets session Id and question Id. The controller asks for the session actor from QuizSessionCoordinatorActor. If the session actor is already available it will be returned else QuizSessionCoordinatorActor will create a new session actor under its context. QuizSessionActor loads the quiz from the QuizTemplateActor in the initial creation, gets the fresh copy of the quiz and returns the requested question. Consequent requests will be served directly by the QuizSessionActor.
    2. GetAnswer – This action methods takes the session Id and the answer for the question and pass it to the right QuizSessionActor for the update.

The entire QuizSessionActor tree is created upon the request for a question under a specific session and this is quite safe and straight forward.

You can download the source code from this Github repo.

Detailing ASP.NET Core in Azure App Service

ASP.NET core is the next generation development standard for the .NET world – may be that’s how I like to express it. Every ASP.NET Core application is a DNX (.NET Execution Environment) application.

When you create an ASP.NET Core application in Visual Studio (VS) 2015, it creates the project targeted at both the .NET Framework and .NET Core. You can see this under the frameworks section of the project.json file. Also the ASP.NET Core team recommends to leave this settings as it is. (Refer : https://docs.asp.net/) letting your application targets both the frameworks.

But in order to understand how things are deployed in the Azure App Service, I compiled an ASP.NET Core application and published it to an Azure Web App. Then I browsed the app with Kudu services and the Process Explorer looked like this, which shows ASP.NET Core app is running on DNX.

image

Under the Debug Console of the Kudu services in the following path site\approot\runtimes we can see the shipped .NET Core runtime, a feature which makes ASP.NET Core applications self-contained.

image

All these information are hidden from the developers and let them focus on the application development. So though the Visual Studio publishing model of the ASP.NET Core application is same as ASP.NET application publish model, based on the defined configurations Azure App Service hosts your web application under different runtimes.