Create blazor library project in the Visual Studio 2019 preview

Correct way is to create ASP.NET Core Web Application and in the second step select “Razor Class Library” project template.

If you create Standard or AspNet.Core library directly then your project file will not contain correct setup for razor component source generation, but you can easily correct this manually:

The correct .csproj file structure of razor library project

<Project Sdk="Microsoft.NET.Sdk.Razor">

  <PropertyGroup>
    <TargetFramework>netcoreapp3.0</TargetFramework>
    <AddRazorSupportForMvc>true</AddRazorSupportForMvc>
  </PropertyGroup>

  <ItemGroup>
    <FrameworkReference Include="Microsoft.AspNetCore.App" />
  </ItemGroup>

</Project>

 

_Imports.razor file

Imports razor file can contain any number of statements (usually centralized using statements). The file will be automatically included in all razor component files in the folder and all subfolders of imports file.

@using MatBlazor
@using Bisaga.Organization.Web.Pages;

Razor files and coresponding code behind file naming convension

If we want to have “code behind” files (with csharp code) hidden “under” the razor file (in Visual Studio) then you need to name components with the same name and additional suffix “.cs”.

Example:

The name of the component “BsgCompanyForm.razor” and the code behind with “functions” in csharp file named “BsgCompanyForm.razor.cs”. But don’t forget that the name of the class cannot be the same as the component name (in this case “BsgCompanyForm” but we usually add some additional suffix in the class name too.

Both files are then connected with the @inherits statement

BsgCompanyForm.razor file:

@inherits BsgCompanyFormBase

<h1>Company</h1>

BsgCompanyForm.razor.cs file:

using Bisaga.Framework.Web;
using System;
using System.Collections.Generic;
using System.Text;

namespace Bisaga.Organization.Web.Pages
{
    public class BsgCompanyFormBase : BsgPageBase
    {
    }
}

If you need to include additional resources (as javascript, CSS) to the project for the final web project deployment, use EmbeddedBlazorContent library: http://bisaga.com/blog/programming/embeddedblazorcontent-how-to-include-static-content-from-blazor-libraries/

EmbeddedBlazorContent – how to include static content from blazor libraries

If you want to include some static resources from the Blazor component library use “EmbeddedBlazorContent” tool.

Source: https://github.com/SamProf/EmbeddedBlazorContent

Create static content in Blazor component library

Create “content” folder in the root of the library project and add CSS and JS files in.

Add embeded resource build action on all the files

Open properties on each resource file and select “Embedded resource” build action on it.

Additional attributes for embedded resource in the project file

Open .CSPROJ project file and edit EmbeddedResource definition to have additional LogicalName definition.

For CSS files:

  <LogicalName>blazor:css:%(RecursiveDir)%(Filename)%(Extension)</LogicalName>

For JS files:

 <LogicalName>blazor:js:%(RecursiveDir)%(Filename)%(Extension)</LogicalName>

Sample:

  <ItemGroup>
    <EmbeddedResource Include="content\bisaga_core.css">
      <LogicalName>blazor:css:%(RecursiveDir)%(Filename)%(Extension)</LogicalName>
      <CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
    </EmbeddedResource>
    <EmbeddedResource Include="content\bisaga_core.js">
      <LogicalName>blazor:js:%(RecursiveDir)%(Filename)%(Extension)</LogicalName>
      <CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
    </EmbeddedResource>
  </ItemGroup>

Add EmbeddedBlazorContent library to blazor server side web project

Startup.cs

Add configuration for embeded content library to Configure metod in Startup.cs

# Startup.cs
app.UseEmbeddedBlazorContent(typeof(Bisaga.Core.Components.BsgComponentBase).Assembly);

_Host.cshtml

Add call to EmbeddedBlazorContent where you wish to include embedded files.

@using EmbeddedBlazorContent

<head>
  ...
    @Html.EmbeddedBlazorContent()
</head>

Syncfusion EJ2 AspNet Core Blazor components installation

If you need professional and supported set of components for server side / client side Blazor web applications use Syncfusion components.

More info:

Installation – NuGet packages :

  • Syncfusion.EJ2.Blazor

Startup.cs

Configure method

Licensing is not needed in case of preview version and library don’t even contain “Licensing” namespace.

// Register Syncfusion license
Syncfusion.Licensing.SyncfusionLicenseProvider.RegisterLicense("...licence string...");

_Host.cshtml

@addTagHelper *, Syncfusion.EJ2.Blazor

<head>
    <link href="https://cdn.syncfusion.com/ej2/17.2.39/bootstrap4.css" rel="stylesheet" />
    <!--    <link href="https://cdn.syncfusion.com/ej2/17.2.39/material.css" rel="stylesheet" />-->
    <!--    <link href="https://cdn.syncfusion.com/ej2/17.2.39/fabric.css" rel="stylesheet" />-->
    <script src="https://cdn.syncfusion.com/ej2/17.2.29/dist/ej2.min.js"></script>
    <script src="https://cdn.syncfusion.com/ej2/17.2.29/dist/ejs.interop.min.js"></script></head>

_Imports.razor

@using Syncfusion.EJ2.Blazor<br>
@using Syncfusion.EJ2.Blazor.Calendars

Components usage in razor files

@page "/"
<h1>Hello, world!</h1>
Welcome to your new app.
<br />
<EjsCalendar></EjsCalendar>

The result

If everything is deployed as expected you should see similar result page:

MatBlazor components installation

AspNet Core – Server side Blazor framework

Source: https://www.matblazor.com/

If you need open source components for Blazor you definitively need to look at MatBlazor component library.

Installation

  • MatBlazor nuget library
  • EmbeddedBlazorContent nuget library (for server side blazor projects)

Startup.cs

Configure method

// Embedded blazor content get static content from depended DLLs 
app.UseEmbeddedBlazorContent(typeof(MatBlazor.BaseMatComponent).Assembly);

_Imports.razor

Add additional “using” statement for MatBlazor

@using MatBlazor

_Host.cshtml

@addTagHelper *, MatBlazor
@using EmbeddedBlazorContent

<head>
    <!-- static resources from dependent blazor libraries -->
    @Html.EmbeddedBlazorContent()
</head>

Application bar sample

In the NavMenu.razor file add:

<MatAppBarContainer>
    <MatAppBar Fixed="true">
        <MatAppBarRow>
            <MatAppBarSection>
                <MatIconButton Icon="menu"></MatIconButton>
                <MatAppBarTitle>Trade scanner</MatAppBarTitle>
            </MatAppBarSection>
            <MatAppBarSection Align="@MatAppBarSectionAlign.End">
                <MatIconButton Icon="favorite"></MatIconButton>
            </MatAppBarSection>
        </MatAppBarRow>
    </MatAppBar>   
</MatAppBarContainer>

After compile your application should look something like :

Blazor components are encoded without namespaces, it means @addTagHelper and @using statements are in place and working.

Database migrations with FluentMigrator

How to setup database migrations in AspNet Core 3 project and SQLite database

Add NuGet packages to projects with migration classes (data layer library):
– FluentMigrator
– Microsoft.Data.Sqlite

Add two additional NuGet packages to AspNet Core web project :
– FluentMigrator.Runner
– FluentMigrator.Runner.SQLite

Configure Startup.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.HttpsPolicy;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;

using FluentMigrator.Runner;
using FluentMigrator.Runner.Initialization;
using Bisaga.Core.Data.Model.Common;
using Trade.Core.Data.Model;


namespace Trade.Scanner
{
     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.
        // For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddRazorPages();
            services.AddServerSideBlazor();

            //Setup data migrations 
            services.AddFluentMigratorCore()
                .ConfigureRunner(rb => rb
                    // Add SQLite support to FluentMigrator
                    .AddSQLite()
                    // Set the connection string
                    .WithGlobalConnectionString(Configuration.GetConnectionString("DefaultConnection"))
                    // Define the assemblies containing the migrations
                    .ScanIn(typeof(Company).Assembly).For.Migrations()
                    .ScanIn(typeof(Exchange).Assembly).For.Migrations()
                ).AddLogging(lb => lb
                    .AddFluentMigratorConsole());


            // Setup services 
            //services.AddSingleton<WeatherForecastService>();
        }

        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IWebHostEnvironment env, IMigrationRunner migrationRunner)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }
            else
            {
                app.UseExceptionHandler("/Home/Error");
                // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
                app.UseHsts();
            }

            app.UseHttpsRedirection();
            app.UseStaticFiles();

            app.UseRouting();

            app.UseEndpoints(endpoints =>
            {
                endpoints.MapBlazorHub();
                endpoints.MapFallbackToPage("/_Host");
            });

            // Run database migrations 
            migrationRunner.MigrateUp();
        }
    }
}

Part of the statement: “.ScanIn(typeof(Company).Assembly).For.Migrations()” is where we define assembly (DLL) where the migration classes are. In case of multiple libraries we simply repeat same method again. The class defined in the “typeof” function could be any class from the targeted assembly.

Migration runner – MigrateUp procedure

To migrate database up we define interface of migration runner in the “Configure” method as parameter. The dependency injection will give us an instance of runner on which we run “MigrateUp” on. Configure will run immediately after ConfigureServices in the application start process.

Sample migration class

using System;
using System.Collections.Generic;
using System.Text;
using FluentMigrator;
namespace Bisaga.Core.Data.Migrations
{
  [Migration(201907061936)]
  public class AddCompanyExhangeStock : Migration
  {
    public override void Up()     {         
     Create.Table("Company")
       .WithColumn("Code").AsString().PrimaryKey().NotNullable().Unique()
       .WithColumn("Name").AsString()
       .WithColumn("DefaultUrl").AsString();

     Create.Table("Exchange")
       .WithColumn("Id").AsInt64().PrimaryKey().NotNullable().Unique().Identity()
       .WithColumn("Name").AsString().Unique().NotNullable()
       .WithColumn("Url").AsString().Nullable();

     Create.Table("Stock")
       .WithColumn("Symbol").AsString().PrimaryKey().NotNullable().Unique()
       .WithColumn("IssuerName").AsString().Unique().NotNullable()
       .WithColumn("ExchangeId").AsInt64().ForeignKey("Exchange", "Id");
    }


    public override void Down()     {         
       throw new NotImplementedException();
    } 
  }
}

More informations :

https://fluentmigrator.github.io/