Wednesday, December 21, 2022

.Net Dependency Injection

.Net Dependency Injection Service Lifetimes:


Transient

Transient lifetime services are created each time they are requested.

Example:

services.AddTransient<IRequest, MyAppRequest>();


Scoped

For web applications, a Scoped lifetime indicates that services are created once per client connection.

Example:

services.AddScoped<ISettings, ClientSettings>();


Singleton

Singleton lifetime services are created the first time they are requested.  

Accessing application configuration or loading static data are examples of when to use Singleton service.

Example:

services.AddSingleton<ISettings, MyAppSettings>();


Extension Methods:

AddBlobServiceClient

Add Azure Blob Storage

Example:


AddDbContext

A Scoped lifetime service used with Entity Framework Core to connect to a database.

Example:

services.AddDbContext<DataContext>(options => options.UseSqlServer("name=ConnectionStrings:SQLConnectionString"), ServiceLifetime.Scoped);


AddOptions

Extension method for adding configuration related options services to the DI container

Example:


AddQueueServiceClient

Azure Queue Service Client. 

Example:


AddSecretClient

Azure Key Vault Secrets

Example:


AddSqlServer

Registers the given Entity Framework DbContext as a service in the IServiceCollection and configures it to connect to a SQL Server database.

Example:

services.AddSqlServer<DataContext>(hostContext.Configuration["ConnectionStrings:SQLConnectionString"]);


Wednesday, November 2, 2022

Power BI RANKX DAX Function

Power BI examples using the RANKX() DAX function.

TravelerRank = RANKX(ALL(Traveler),Traveler[Traveler Name],,DESC,Dense)

Traveler Rank by Air Tickets =
VAR MeasureValue = [Air Tickets]
VAR MaxRank = CALCULATE(MAX(Traveler[TravelerRank]),REMOVEFILTERS())
VAR LookupTable = ADDCOLUMNS(ALL(Traveler)
    ,"@Total", [Air Tickets] * MaxRank + Traveler[TravelerRank]
)
VAR CurrentName = SELECTEDVALUE ( Traveler[Traveler Name] )
VAR CurrentNameRanked = RANKX ( ALL ( Traveler), Traveler[Traveler Name], CurrentName, DESC, DENSE )
VAR CurrentValue = MeasureValue * MaxRank + CurrentNameRanked
VAR retval = RANKX(LookupTable,[@Total],CurrentValue,,Dense)
RETURN retval

Source: https://learn.microsoft.com/en-us/dax/rankx-function-dax

Monday, October 17, 2022

Angular Packages

 Angular Packages (https://angular.io/guide/npm-packages#angular-packages)

@angular/animations - Animations library

@angular/common - Required. commonly-needed services, pipes, and directives.  HttpClientModule

  • /http/HttpClientModule - Configures the dependency injector for HttpClient with supporting services for XSRF
  • /http/HttpClientJsonpModule - Configures the dependency injector for HttpClient with supporting services for JSONP

@angular/compiler - Required. Angular's template compiler

@angular/core - Required. Critical runtime parts of the framework.  Component, Directive, dependency injection, lifecycle hooks

  • NgModule - Decorator that marks a class as an NgModule and supplies configuration metadata.  Used in app.module.ts
  • Component - Decorator that marks a class as an Angular Component and provides configuration metadata that determines how the component should be processed, instantiated, and used at runtime.  Components provide data to the view.
  • Directive - Decorator that marks a class as an Angular Directive.  Directives are used to add additional behavior to an existing DOM.  CSS attributes for example.
  • Injectable - Decorator that marks a class as available to be provided and injected as a dependency.  A service is an example of an injectable.
  • OnInit - A lifecycle hook that is called after Angular has initialized all data-bound properties of a directive.

@angular/forms - Support for both template-driven and reactive forms

  • FormsModule - Rely on directives in the template to create and manipulate the underlying object model.  Template-driven Forms use mutable data with two-way data binding to update the data model in the component as changes are made in the template.  Change detection is less efficient at determining when updates are required
  • ReactiveFormsModule - Provide direct, explicit access to the underlying form's object model.  Reactive Forms use immutable data.  Each time a change is triggered on the data model, the FormControl instance returns a new data model rather than updating the existing data model
  • FormControl - Tracks the value and validation status of an individual form control

@angular/platform-browser - Everything DOM and browser related

  • BrowserModule - Exports required infrastructure for all Angular apps. Used in app.module.ts

@angular/platform-browser-dynamic - Includes providers and methods to compile and run the application on the client using the JIT compiler.

  • platformBrowserDynamic - Used in main.ts and implements AppModule in app.module.ts

@angular/router - The router module navigates among your application pages when the browser URL changes

  • RouterModule - Adds directives and providers for in-app navigation among views defined in an application.
  • Routes - service that provides navigation among views and URL manipulation capabilities


Support Packages for Angular

rxjs - implementation of Observables

  • Observable - represents a stream, or source of data that can arrive over time

tslib - runtime library for TypeScript 

zone.js - Angular relies on zone.js to run Angular's change detection processes when native JavaScript operations raise events


Angular Development / Build Dependent Packages

@angular-devkit/build-angular - Angular build tools

@angular/cli - Angular CLI tools

@angular/compiler-cli - Angular compiler, which is invoked by the Angular CLI's ng build and ng serve commands

@types/jasmine - TypeScript definition files for 3rd party libraries such as Jasmine and Node.js

jasmine-core - Packages to support the Jasmine test library.

karma - Packages to support the karma unit test runner.

karma-chrome-launcher

karma-coverage

karma-jasmine

karma-jasmine-html-reporter

typescript - The TypeScript language server, including the tsc TypeScript compiler.


Additional Packages used with Angular

@angular/material - Material Design components for Angular

@angular/cdk - Material Design Component Dev Kit (CDK) is a set of behavior primitives for building UI components

@azure/msal-angular - Microsoft Authentication Library for JavaScript Angular Wrapper

@azure/msal-browser - Microsoft Authentication Library for JavaScript v2 browser package

@microsoft/microsoft-graph-client - Microsoft Graph API JavaScript client library

@ng-bootstrap/ng-bootstrap - Bootstrap components for Angular

jest-editor-support - unit test runner based on executing directly in Node

Tuesday, October 4, 2022

Power BI DAX add Column from another table

 Power BI DAX code to add a column to a table from a lookup / LOV table.

This example adds the "Airline Carrier's Name" to the Air Tickets table using the Airline Carriers IATA ID.

Airline = LOOKUPVALUE('Airline Carrier'[Airline],'Airline Carrier'[CarrierCode],'Air Ticket'[CarrierCode])


Source: https://learn.microsoft.com/en-us/dax/lookupvalue-function-dax

Thursday, September 22, 2022

Power BI CountRows DAX Function

 In Power BI, when counting rows in a table it is advised to use the COUNTROWS() DAX function instead of COUNT().  Use the COUNT() function only when you want to count the number of rows that do not have a blank value in the specified column.

Example:

Air Tickets = CALCULATE(

    COUNTROWS('Air Ticket')

    ,USERELATIONSHIP('Calendar'[Date],'Air Ticket'[Issued Date])

)


Source: https://learn.microsoft.com/en-us/dax/best-practices/dax-countrows

Monday, September 19, 2022

Power BI DIVIDE DAX Function

 In Power BI, when dividing 2 number it is advised to use the DIVIDE() DAX function instead of the divide operator (/).

Syntax: DIVIDE(<numerator>, <denominator> [,<alternateresult>])

Example: % of Total Sales Amount = DIVIDE([Sales Amount], [Total Sales Amount],0.0)


Source: https://learn.microsoft.com/en-us/dax/best-practices/dax-divide-function-operator

Power BI Row Level Security

Power BI has the capability to filter data by user.  One of the ways to do this is by using the email address of the user that is signed in to Power BI using the UserPrincipalName() DAX function.

This can be done using a SQL table, CSV file, SharePoint list, etc. to manage what users have access to.  In this example I'll use a SQL table with a foreign key constrain to my crm.Contacts table to manage which contacts a user has access to.


Step 1. Create a SQL table for Row Level Security.


Step 2. Add records to the pbi.RowLevelSecurity table.

INSERT INTO pbi.RowLevelSecurity(EmailAddress,ContactID) VALUES ('bespencer1@gmail.com',5);






Step 3: Add the pbi.RowLevelSecurity table to your Power BI dataset.  Do this in Power BI Desktop

let

    Source = Sql.Database(".", "MyDB"),

    pbi_RowLevelSecurity = Source{[Schema="pbi",Item="RowLevelSecurity"]}[Data]

in

    pbi_RowLevelSecurity

Step 4.  Create the relationship between pbi.RowLevelSecurity and the crm.Contacts table.  

PowerBI will automatically do this for you if you have a Foreign Key in SQL Server.

Set the relationship to "Both" cross filter direction and check the "Apply security filter in both directions".

Power BI Security Relationship


Step 5.  Create a Power BI Role and add this table filter on pbi.RowLevelSecurity

[EmailAddress] = userprincipalname()

Power BI Create Role




Step 6.  Test the Row Level Security confirmation using the "View as" option.  

Check the box beside the role you created in the previous step and check the box beside Other user. 

Enter the email address of the user you want to test and click OK.  Power BI is not applying the Row Level Security filter to your data.

Power BI View As Role

Step 7.  Publish to Power BI Online.

Publish the Power BI report to Power BI Online using the "Publish" button in Power BI Desktop.

Power BI Desktop Publish



Step 8:  Grant users Viewer access to the Power BI report.

Open the Workspace the Power BI report was published to.  Click the Manage Access button and add users with "Viewer" access to the workspace.  You can also grant users Viewer access to the Power BI report only depending on your security needs.


Step 9:  Add members to the Row-Level Security role you created.

Open the Workspace the Power BI report was published to.  Click the "More Options" button next to the Dataset and select "Security".

Dataset Security menu


On the Row-Level Security screen, select the Row Level Security role you created and "Add" users as members of that role.  

Row-Level Security Add Member

Please note that Row-Level Security only works for user with "Viewer" access.  Users with elevated access including Member and Admin will have access to all of the data included in the dataset.


 


Monday, August 22, 2022

Power BI Calculate DAX Function

In Power BI, I use CALCULATE in almost all measure.

Syntax: CALCULATE(<expression>[, <filter1> [, <filter2> [, …]]])


Here is an example of the CALCULATE function where is specify which Date relationship I want the calculation to use when determine the total number of unique Air Tickets, excluding Refunded and Voided tickets.

Air Tickets = CALCULATE(DISTINCTCOUNTNOBLANK('Air Ticket'[Ticket Number])
, USERELATIONSHIP('Calendar'[Date],'Air Ticket'[Issued Date])
, KEEPFILTERS('Air Ticket'[Ticket Status] <> "Refund")
, KEEPFILTERS('Air Ticket'[Ticket Status] <> "Voided")
)

Source: https://learn.microsoft.com/en-us/dax/calculate-function-dax

Friday, July 8, 2022

SQL Server List Partitioned Tables with Row Count and Page Size

SQL Server script to list database tables that are partitioned with the partitions schema, partition function, row count, page size, and partition range.