Integrate NDepend into your .Net Core projects !

Introduction

In computer science and software engineering in particular, software quality is an overall assessment of software, based on many indicators.

The completeness of the features, the correction and precision of the results, the reliability, the fault tolerance, the facility and the flexibility of its use, the simplicity, the extensibility, the compatibility and the portability, the facility of correction and transformation, the performance, consistency and integrity of the information it contains are all quality factors.

In software engineering, factorization of data and code is the universal means of obtaining quality.

We will talk in this article about NDepend, a tool to help software developers to achieve a high level of quality of their programs.

What is NDepend ?

 

NDepend was created by Patrick Smacchia in 2004, it became commercial in 2007 and evolved a lot since.

It does static code analysis for .NET and you can try it free for 14 days.

NDepend can be used in standalone or integrated Visual Studio mode.

This tool gives you one-click access to many metrics in your code with a graphical representation. Interesting!

With the dashboard the most interesting feature of NDepend is the query language on which it is built: CQLinq

But before let’s take a look on the installation process.

Installation

Installing the NDepend extension for Visual Studio is really easy, download it and install like this by clicking on Visual Studio Extension Installer and then select the Visual Studio version you to install on:

The great thing about NDepend is the ease with which you can get started and the excellent documentation available in their website. There are online videos, tutorials, screenshots, step by step explanations and you cannot go wrong with it.

For more details you can go here for: https://www.ndepend.com/docs/getting-started-with-ndepend#Tuto

Running NDepend

You can run NDepend in standalone with VisualNDepend.exe executable (in the same installation directory than the Visual Studio Extension executable) or run the extension in Visual Studio from the menu:

When you expend the menu you can access to NDepend features.

Let’s see how Dashboard looks like:

On the same screen, NDepend provides many many metrics like :

  • Technical Debt
  • Lines of code
  • Comments
  • Issues
  • Programming rules
  • Code coverage
  • Quality gates
  • And more other features

It provides really huge analysis of your code, you can at anytime take a look at a little summary and recompute your dashboard by clicking on the colored circle at bottom right of your screen, very convenient!

 

Let’s see another crazy feature of NDepend:  CQLinq

CQLinq, which stands for Query Code LINQ, is a query language that you can execute on an abstract model of your code. In concrete terms, you can query your code the same way you would query the views or tables of a database. For example, to search all class constructors, I wrote the following query:

from m in Methods 
where m.IsConstructor
select m

If you want to write your query, go on the NDepend menu, select “Rules” and View “Editor Panel“:

It open a little window where you can type your query, at the same time, the result is displayed at the bottom, nice isn’t it? 🙂

 

There is also VSTS integration:

You can integrate NDepend to your TFS CI/CD process by leveraging a VSTS extension and adding it to your build definition. You can also define a Quality Gate for your project, and fail the build when code quality is not met.

There are also TeamCity, Jenkins, SonarQube and FinalBuilder integration if you don’t use VSTS.

Conclusion

I did not introduce every features of NDepend because it’s a very big and complete product, I chose the most interesting features according to me.

I didn’t precise that all NDepend results can be diff-ed since a baseline:  https://www.ndepend.com/docs/code-diff-in-visual-studio

I didn’t dig into Technical-Debt capabilities:
https://www.ndepend.com/docs/technical-debt that NDepend has facilities to explore dependencies with code graph and DSM (Dependency Structure Matrix)
https://www.ndepend.com/docs/visual-studio-dependency-graph
https://www.ndepend.com/docs/dependency-structure-matrix-dsm
https://www.ndepend.com/docs/cqlinq-features#Dependencies that NDepend can import code coverage data and use it in some rule…
https://www.ndepend.com/docs/treemap-visualization-of-code-metrics#Color

I honestly think NDepend is very powerful and very easy to use. The CQLinq language and the NDepend dashboard are in fact the best features of the tool and in addition I have found nothing equivalent at this level.

However, because NDepend doesn’t correct code for you, I suggest to keep using Resharper that can work in synergy with NDepend. There are few overlap between the NDepend and Resharper rules-sets, while Resharper is more focused on details inside methods body, NDepend focuses more on code structure and overall quality.

The NDepend team is very active and we can expect a lot of good developments in future versions.

I thank Patrick Smacchia, for giving me the opportunity to test his product that I find really excellent.

Patrick when a NDepend-like for SPAs ? 😉

Using OpenIdConnect with Azure AD, Angular5 and WebAPI Core: WebAPI configuration

 

Installing required packages

There is only one required package to achieve our Web Api protection with a JWT.

Install https://www.nuget.org/packages/Microsoft.AspNetCore.Authentication.JwtBearer/

PM> Install-Package Microsoft.AspNetCore.Authentication.JwtBearer -Version 2.0.1

Configure your Web API in Startup.cs:

using System;
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;

namespace WebApiJwtBearer
{
   public class Startup
   {
      public Startup(IConfiguration configuration)
      {
         Configuration = configuration;
      }

      public IConfiguration Configuration { get; }

     //This method gets called by the runtime. Use this method to add services to the container.
     public void ConfigureServices(IServiceCollection services)
     {
        services.AddAuthentication(options =>
        {
           options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
           options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
        }).AddJwtBearer(options =>
        {
           options.Authority = "https://login.microsoftonline.com/136544d9-038e-4646-afff-10accb370679"; <- tenantId
           options.Audience = "257b6c36-1168-4aac-be93-6f2cd81cec43"; <- clientId
           options.TokenValidationParameters.ValidateLifetime = true;
           options.TokenValidationParameters.ClockSkew = TimeSpan.Zero;
       });

       services.AddAuthorization();

       services.AddMvc();
    }

    //This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
    public void Configure(IApplicationBuilder app, IHostingEnvironment env)
    {
       if (env.IsDevelopment())
       {
          app.UseDeveloperExceptionPage();
       }

      app.UseAuthentication();

      app.UseCors(builder => builder
      .AllowAnyOrigin()
      .AllowAnyMethod()
      .AllowCredentials()
      .AllowAnyHeader());
      app.UseMvc();
   }
 }
}

Now you should be done 🙂

Let’s see what happen if we test it :

 

Nice isn’t it? 🙂

Using OpenIdConnect with Azure AD, Angular5 and WebAPI Core: Angular5 configuration

 

Install required packages and setup Angular 5 application

Firstly install the latest version of Angular with Angular-CLI

npm install -g @angular/cli

Then install an angular version of ADAL.JS:  adal-angular5

npm install --save adal-angular5

Create a AuthService

We will create a AuthService.ts, this service will manage signin, signout and users data :

auth.service.ts:

import { Adal5HTTPService, Adal5Service } from 'adal-angular5';
import { HttpClient, HttpHandler } from '@angular/common/http';
import { Injectable } from '@angular/core';
import { Observable } from 'rxjs/Observable';

@Injectable()
export class AuthService {

private_user=null;
private_config = {
   tenant:'136544d9-038e-4646-afff-10accb370679', <-- tenantId mentionned in the previous article
   clientId:'257b6c36-1168-4aac-be93-6f2cd81cec43', <-- clientId mentionned in the previous article
   redirectUri:"http://localhost:4200/auth-callback", <-- callback URI mentionned in the previous article
   postLogoutRedirectUri:"http://localhost:4200" <-- same URI as homepage URI mentionned in the previous article
}

constructor(private_adal:Adal5Service) {
   this._adal.init(this._config);
}

public isLoggedIn():boolean {
   return this._adal.userInfo.authenticated;
}

public signout():void {
   this._adal.logOut();
}

public startAuthentication():any {
   this._adal.login();
}

public getName():string {
   return this._user.profile.name;
}

public completeAuthentication():void {
   this._adal.handleWindowCallback();
   this._adal.getUser().subscribe(user=> {
   this._user=user;
   console.log(this._adal.userInfo);
   var expireIn=user.profile.exp-newDate().getTime();
});

}

}

this service is the most important thing, it will be used everywhere in the application.

Create a AuthGuardService

This AuthGuard service is usefull for protecting your page with authentication

You need to implement CanActivate method using Interface with the same name:

auth-guard.service.ts:

import { AuthService } from './auth.service';
import { Injectable } from '@angular/core';
import { CanActivate } from '@angular/router';

@Injectable()
export class AuthGuardService implements CanActivate {

constructor(private_authService:AuthService) { }

   canActivate():boolean {

   if(this._authService.isLoggedIn()) {
      return true;
   }
   this._authService.startAuthentication();
    return false;
   }

}

CanActivate is fired when you try to access to a route that is protected.

To setup route protection, create a component served by a protected route you want to protected with authentication, and setup route protection in app.module.ts:

Example of a protected component:

protected.component.ts:

import { AuthService } from './../services/auth.service';
import { Component, OnInit } from '@angular/core';

@Component({
   selector:'app-protected',
   templateUrl:'./protected.component.html',
   styleUrls: ['./protected.component.css']
})

export class ProtectedComponent implements OnInit {

   name:String="";
   constructor(private_authService:AuthService) { }

   ngOnInit() {
      this.name=this._authService.getName();
   }

   public signout():void {
      this._authService.signout();
   }
}

protected.component.html:

<p>

Welcome {{name}}

</p>

<a href="javascript:void(0);" (click)="signout();">signout</a>

Protect your routes like this in app.module.ts:

const routes: Routes = [
{
   path:'',
   children: []
},
{
   path:'protected',
   component:ProtectedComponent,
   canActivate: [AuthGuardService]
},
{
   path:'auth-callback',
   component:AuthCallbackComponent
}
];

Create a AuthCallback component

This component will be used as endpoint in your app to manage user creation after receiving the token from Azure Authorization endpoint.

Azure AD will call your page and send the token. If you remember well, the URI has to be declaqred in Azure to make it work.

auth-callback.component.ts:

import { AuthService } from './../services/auth.service';
import { Router, ActivatedRoute } from '@angular/router';
import { Component, OnInit, NgZone } from '@angular/core';

@Component({
   selector:'app-auth-callback',
   templateUrl:'./auth-callback.component.html',
   styleUrls: ['./auth-callback.component.css']
})

export class AuthCallbackComponent implements OnInit {

   constructor(private_router:Router, private_authService:AuthService, private_zone:NgZone, private_activatedRoute:ActivatedRoute) { }

   ngOnInit() {
      this._authService.completeAuthentication();

      setTimeout(() => {this._zone.run(
      () => this._router.navigate(['/protected'])
      );},200);
   }
}

auth-callback.component.html:

<p>Please wait while we redirect you back</p>

The method completeAuthentication is in fact internally a Promise but I execute the redirection after authentication synchronously by using a setTimeout statement.

I used also NgZone object.

Why this?

Passing a callback to promise after authentication in completeAuthentication did not work on Safari IOS, so the work around was using setTimeout inside NgZone… a bit dirty but it works! 🙂

Modify you app.component.html to test a protected route:

<h3><a routerLink="/">Home</a> | <a routerLink="/protected">Protected</a></h3>
<h1>
{{title}}
</h1>
<router-outlet></router-outlet>

Check your app.module.ts

Your app.module.ts should be well setup like this:

import { AuthService } from './services/auth.service';
import { AuthGuardService } from './services/auth-guard.service';
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';
import { AppComponent } from './app.component';
import { ProtectedComponent } from './protected/protected.component';
import { AuthCallbackComponent } from './auth-callback/auth-callback.component';
import { Adal5Service, Adal5HTTPService } from 'adal-angular5';
import { HttpClient } from '@angular/common/http';
const routes: Routes = [
{
   path:'',
   children: []
},
{
   path:'protected',
   component:ProtectedComponent,
   canActivate: [AuthGuardService]
},
{
   path:'auth-callback',
   component:AuthCallbackComponent
}
];

@NgModule({
   declarations: [
      AppComponent,
      ProtectedComponent,
      AuthCallbackComponent
   ],
   imports: [
      BrowserModule,
      RouterModule.forRoot(routes)
   ],
   exports: [RouterModule],
   providers: [AuthGuardService, AuthService, Adal5Service,{ provide:Adal5HTTPService, useFactory:Adal5HTTPService.factory, deps: [HttpClient, Adal5Service] } ],
   bootstrap: [AppComponent]
})

export class AppModule { }

Demo time !!!

If everything is well setup in Azure and in your Angular 5 application, if you try to go to navigate to a protected route you should have a logging page to Microsoft and be redirected to your web application:

 

 

 

 

 

If log in your browser console the authenticated user object you should have something like this :

Awesome right ? 😉

Now let’s see how we protect a Web Api: Using OpenIdConnect with Azure AD, Angular5 and WebAPI Core: WebAPI configuration