Blazor Means Business: Enhancing Enterprise Architecture Delivery with Paul Schroeder
Embrace the power of Blazor in driving business success with insights from Paul Schroeder at MSC Technology Consulting. Connect with the real Paul Schroeder on GitHub and explore rapid enterprise architecture delivery through initiatives like Xamarin Developers Summit 2019.
Download Presentation
Please find below an Image/Link to download the presentation.
The content on the website is provided AS IS for your information and personal use only. It may not be sold, licensed, or shared on other websites without obtaining consent from the author. Download presentation by click this link. If you encounter any issues during the download, it is possible that the publisher has removed the file from their server.
E N D
Presentation Transcript
Blazor Means Business Paul Schroeder MSC Technology Consulting @PaulBSchroeder @PaulBSchroeder RealPaulSchroeder RealPaulSchroeder paul@msctek.com paul@msctek.com
xamarindevelopersummit/XamDevSummit2019 GitHub: Rapid Enterprise Architecture Delivery Rapid Enterprise Architecture Delivery Xamarin Developer Summit 2019 Xamarin Developer Summit 2019 youtube.com/watch?v=oZc1Nquxvlk
Dedicated to K. Scott Allen June 11, 1969 - January 10, 2020 Microsoft Regional Director and MVP Founder of OdeToCode Founding Pluralsight author (54 courses) Frequent Conference Speaker CTO, Consultant, Trainer The Blazor Bet Tuesday, September 24, 2019 odetocode.com/blogs/scott/archive/2019/09/24/ the-blazor-bet.aspx Head to Head: Scott Allen and Jon Skeet - Scott Hanselman youtu.be/H2KkiRbDZyc NDC (Sydney) Aug 29, 2016
What is Blazor? A feature of ASP.NET Core Build interactive web UIs using C# Composed of reusable components (C#, HTML, and CSS) C# for both client and server code Enables sharing of code and libraries @csharpfritz @danroth27 JavaScript As Needed
What isnt Blazor? Yeah, I remember the same WPF hype and WCF and Silverlight and LightSwitch and W8 Store and . Not the new shiny ! Not the new shiny ! Smooth & Business Savvy Surprisingly simple Straight forward & predictable behavior Few surprises Promising development experience @ @PaulBSchroeder PaulBSchroeder
Oct 2019 Oct 2019 Blazor Roadmap May 2020 (not LTS) May 2020 (not LTS) https://aka.ms /blazorelectron /webwindow blazormobile Embed a Blazor web app as a standalone mobile app, hosted in Xamarin Deploy as a desktop application with Electron.NET https://visualstudiomagazine.com/articles/2019/09/26/blazor-future.aspx
Welcome to Blazor - Daniel Roth Blazor Future Features - Steve Sanderson Routing A-Z - Chris Sainty Create a great UX with Blazor - Jimmy Engstrom State Management in Blazor Apps - Jeremy Likness JavaScript Two-Way Interop - Javier Calvarro Nelson Testing Blazor Components - Egil Hansen Mobile Blazor Bindings Using Blazor to build mobile apps - Eilon Lipton Authoring Custom Components - Ed Charbeneau Microsoft, Google and Cookie Authentication and Authorization - Michael Washington Scaling Blazor Server Apps with Azure - Ryan Nowak Build Serverless Apps with Blazor - Daria Grigoriu Fabio Cavalcante Blazor for Web Form and C# Developers - Jeff Fritz Blazor Has Momentum
Mobile Blazor Bindings Using Blazor to Build Mobile Apps - Eilon Lipton 6h 29m
2 Flavors: Server Server- -Side Side & Client Client- -Side Side Server-Side Client-Side Limited Debugging Limited Debugging Full Debugging Full Debugging ASP.NET Core Blazor Blazor Razor Components Razor Components DOM .NET (Mono) DOM .NET WebAssembly SignalR Server-side Blazor has the same syntax as the client-side Just copy and paste your server-side code into a client-side Blazor project Independently runs on client device Compiles to binary Wasm = improved performance Network latency => slower Reduced scalability => Memory
Blazor WebAssembly features for May .NET Standard 2.1 WebSockets + .NET SignalR client Debugging (browser dev tools & Visual Studio) Auto-rebuild IL trimming Brotli compression Static web assets integration Authentication options Localization
Create new Blazor server-side project Visualize the SignalR channel Routing State management Server-Side o Offline capability (local storage) Dependency injection => ConfigureServices() Primer Demo! Examine pipeline concept => Configure() Vary by environment Components How did we get here?
Browsers Console & Network Tabs Pending
Sent Received <h1>Weather forecast</h1> <p>This component demonstrates fetching data from a service</p> table.class.table 7468 ... ..<thead>.. <tr>.. 7465 <th>Date 2020 </th>.. 2020 body.... 2020 .tr... 3016 .td.1/12/2020. 6c6d .Balmy
Offline Capability / Local Storage Wraps HTML5 Storage APIs. Both Session and Local storage types are supported. github.com/Blazored/LocalStorage github.com/BlazorExtensions/Storage github.com/cloudcrate/BlazorStorage See .NET Conf 1/14/20 State Management in Blazor Apps - Jeremy Likness 4h 15m
if (env.IsDevelopment()) { // This will push telemetry data through Application Insights pipeline faster, allowing you to view results immediately. builder.AddApplicationInsightsSettings(developerMode: true); } Other Uses for Environment .AddJsonFile("appsettings.json", optional: true, reloadOnChange: true) .AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true) .AddJsonFile($"customSettings.json", optional: true, reloadOnChange: true) Control the diagnostics logging level (Debug, Info, Warning, etc.) Send a minified version of a static file (i.e. *.css / *.js)
Between server-side and client-side (WebAssembly) Blazor, which will Post Post- -Demo Quiz Demo Quiz WebAssembly because it does not have the network latency associated with the SignalR messaging channel Have faster execution? Server-side because it does not have the large download size associated with a .NET Mono runtime (~ 2MB) Loads faster, initially? WebAssembly Even w/C#, Wasm DLLs cannot do anything JavaScript cannot do use API & services instead! Cannot access DbContext? Dan Roth - .NET Conf 1/14/20 Welcome to Blazor 1 h 46m Server-side because that is where the component code executes also best for thin/resource-constrained clients. Work on clients that do not support WebAssembly? Could be designed to work offline? WebAssembly because it can operate completely independent from the Internet, once downloaded.
Giveaway for Tonights CNUG Attendees Free 1-year Subscription Register at CodeGenHero.com Visual Studio 2019 Extension Code Generate Enterprise Architecture Classes Adapt to Requirements Change in Minutes Save Time / Lower Development Cost Eliminate Human Error Bugs (i.e. Copy / Paste) Focus on Business Rules & UI not Plumbing
Any questions at this time? Something you really want to see covered in the advanced session? 10-Minute Intermission! Twitter: @_CNUG #blazor @PaulBSchroeder @danroth27 @CSharpFritz #MakeFritzProud #AwesomePurpleBlazer
Event Portal Unauthorized User Limited Menu Options Register & Log In Buttons RSVP & More Details
Event Portal Partner Access Partner Center Menu Username Greeting Create Event Button Edit, Roster, Survey # of Reservations ?
Event Portal Staff Access Analytics Menu Review Submissions Partner Icon Access to All Events
UserCultureInfo.razor Routing & Navigation Inherits & Dependency Injection Binding (variables & properties) Advanced Demo Items Event Lifecycle Click events Localization UTC vs. Local time JavaScript Runtime IHttpContextAccessor & Cookies
Multiple route templates can be applied to a component. Routing & Navigation Use a NavLink component in place of HTML hyperlink elements (<a>) when creating navigation links. Has an active class feature. App.razor - Use the AdditionalAssemblies parameter for the Router component to look in more places when searching for routable components. Route Constraint @page "/eventdetail/{eventId:int}" Programmatic: Use NavigationManager to work with URIs and navigation in C# code. <Router AppAssembly="typeof(Program).Assembly" AdditionalAssemblies="new[] { typeof(MyCustom).Assembly }"> ... </Router>
SO 2013: How to translate between Windows and IANA time zones? Those provided by Microsoft for use with Windows and the .NET TimeZoneInfo class are identified by a value such as "Eastern Standard Time". Those provided by IANA in the TZDB, and used by the .NET TimeZoneInfo class when running on Linux or OSX, are identified by a value such as "America/New_York". const tz = Intl.DateTimeFormat().resolvedOptions().timeZone; console.log(tz); != Central Standard Time America/Chicago Date Localization Globalization - design applications for multiple cultures. Localization - customize for a given culture and locale.
Convert a UTC date to local time Field to record IANA Time Zone Database Identifier Persist your date fields as UTC Noda Time is a date and time API acting as an alternative to the built-in DateTime / DateTimeOffset etc. types built into the .NET framework. Local Time Zone Using NodaTime Jon Skeet https://nodatime.org/
Event Lifecycle Methods Synchronous as well as asynchronous lifecycle methods are provided. Set a breakpoint in OnParametersSetAsync() of ConferenceEventSignUpVM.cs as you RSVP OnInitialized* are only called one time Execute on component initialization & each time new parameter values are specified OnInitialized OnInitializedAsync OnParametersSet OnParametersSetAsync OnAfterRender OnAfterRenderAsync ShouldRender StateHasChanged firstRender - used to ensure that initialization work is only performed once Return false to prevent changes from being sent to UI
I want the users time zone, but that s a browsersetting and I m on the server . IHttpContextAccessor & Cookies Discouraged for use with SignalR SignalR - no guarantee HttpContext is available github.com/aspnet/AspNetCore.Docs/issues/14974 github.com/dotnet/aspnetcore/issues/14878 Works on my machine IIS Express Development
Architecture & Design Tips Structuring a solution for SoC In-memory providers for rapid prototyping State Management Parameters / Cascading Param Layout Components / Pages Advanced Demo Items
Structure Solutions for Separation of Concerns
Start with Interfaces and Services IConferenceEventService and ConferenceEventMemoryService Create Sample Data Use Singleton with DI not Transient Services: Services: In In- -Memory Data Memory Data Providers Providers
State Management in Blazor Apps - Jeremy Likness .NET Conf 1/14/2020 - 4h 15m 3-ish Options for State Management github.com/jeremylikness/blazorstate 1. In memory - Length of session or connection Client cache via Local Storage Server - Thin client calling API (then persist i.e. DB) Ignore it 2. 3. 4. Encrypted State docs.microsoft.com/en-us/aspnet/core/blazor/state-management timewarpengineering.github.io/blazor-state/ github.com/mrpmorris/blazor-fluxor
Self-contained .razor file (UI) with C# & HTML markup Page, Dialog, Form HTML markup and the processing logic Inject data or respond to UI events Can be nested, reused, and shared among projects Use <component> tag helper Components Components can be developed in a separate project and packaged into NuGet package or Html .RenderCompo nentAsync<> Dan Roth - .NET Conf 1/14/20 - Welcome to Blazor 1 h 26m StarRatings NuGet Package To use a custom folder, add the custom folder's namespace to either the parent component or to the app's _Imports.razor file. @using CGH.EventPortal.Web.Components @using CGH.EventPortal.Web.Shared
@page "/eventdetail/{conferenceeventId:int}" Parameters Parameters BlazoredModal.razor Cascading Cascading Parameters Parameters ConferenceEventSignUpVM.cs
Blazor Layouts Inherit from LayoutComponentBase Component with a Razor template Data binding & DI are supported Body property placeholder for content to be rendered inside the layout. @Body gets replaced by the content of the layout during rendering
Add Some Sizzle Add Font Awesome Material Design Validate Forms Using EditForm Modal Dialogs Toast Service Grid Component Implementation Advanced Demo Items
Add Font Awesome _Host.cshtml - use one or the other, not both stackoverflow.com/questions/5919753 3/how-to-add-font-awesome-to-blazor- client-razor-component-app <link href="lib/font- awesome/css/all.min.css" rel="stylesheet" /> <script src="lib/font- awesome/js/all.min.js"> </script>
Material Design Install MatBlazor library via NuGet _Imports.razor @using MatBlazor _Host.cshtml <script src="_content/MatBlazor/dis t/matBlazor.js"></script> www.matblazor.com/
EditContext Tracks the state of an editing process that knows: oWhich fields have been modified oData entered oWhether or not the fields are valid EditForm Install MatBlazor package via NuGet <EditFormModel="@QuarterlyReport" OnValidSubmit="@HandleValidSubmit"> _Imports.razor @using MatBlazor _Host.cshtml <script src="_content/MatBlazor/dis t/matBlazor.js"></script>
JavaScript-free modal implementation for Blazor and Razor Components applications Modal Dialogs Register Service public void ConfigureServices(IServiceCollection services) { services.AddBlazoredModal(); } Install Blazored.Modal package via NuGet MainLayout.razor <BlazoredModal /> _Imports.razor @using Blazored _Host.cshtml <link href="_content/Blazored.Modal/blazored-modal.css" rel="stylesheet" /> <link href="_content/<assembly>/<path to file> @using Blazored.Modal @using Blazored.Modal.Services github.com/Blazored/Modal
JavaScript-free toast library for Blazor and Razor Components applications Toast Notifications Register Service github.com/Blazored/Toast public void ConfigureServices(IServiceCollection services) { services.AddBlazoredToast (); } Install Blazored.Toast package via NuGet MainLayout.razor <BlazoredToasts /> _Imports.razor @using Blazored.Toast _Host.cshtml <link href="_content/Blazored.Toast/blazored-toast.css" rel="stylesheet" /> <link href="_content/<assembly>/<path to file> @using Blazored.Toast.Services
Grid component with CRUD for Blazor (client/server-side) and ASP.NET Core MVC Data Grid Register Service public void ConfigureServices(IServiceCollection services) { services.AddBlazoredToast (); } Install GridBlazor & GridMvcCore packages via NuGet Quickstart Instructions /blob/master/docs/blazor_server/Quick_start.md _Imports.razor @using GridBlazor.Pages _Host.cshtml <link href="_content/GridBlazor/css/gridblazor.min.css" rel="stylesheet" /> <script src="_content/GridBlazor/js/gridblazor.js"></script> github.com/gustavnavar/Grid.Blazor
Infrastructure Safe Storage of App Secrets EF DbContext DI Strongly-Typed Config Settings Log Configuration UserName Query JSON in SQL Server Advanced Demo Items
Strongly Typed Config Settings using Microsoft.Extensions.Configuration using Microsoft.Extensions.Options; In Startup.cs -> ConfigureServices() services.Configure<AppSettings>( Configuration.GetSection("AppSettings")); AppSettings.json { "ConnectionStrings": { "DefaultConnection": " }, "AppSettings": { "DefaultTzdbTimeZoneId": "America/Phoenix"}} [Inject] protected IOptions<AppSettings> CGHAppSettings { get; set; }
In Startup.cs -> Configure () // Place before UseSerilogRequestLogging to // capture context.User.Identity.Name app.UseMiddleware<Logging.LogUserNameMiddleware>(); // Place after UseStaticFiles to reduce the noise. app.UseSerilogRequestLogging(); Serilog Logging In ViewModel base class -> OnInitialized() private void SetupLogger() { LoggerFactory.CreateLogger(this.GetType()); Logger = if (HttpContextAccessor.HttpContext != null) { Serilog.Context.LogContext.PushProperty("UserName", HttpContextAccessor.HttpContext.User.Identity.Name); } [Inject] protected ILoggerFactory LoggerFactory { get; set; } Logger.LogDebug("OnInitialized invoked in {typeName}", this.GetType().Name); }
{"TimeStamp":"2020-01- 13 ,"Properties":{"typeName":"ConferenceEventListItem", "SourceContext":"Web.Components.ConferenceEventListItem", ,"MachineName":"BATMAN2", "EnvironmentUserName":"AzureAD\\PaulSchroeder", "UserName":"staff@msctek.com"}} [LogEvent] JSON field in Log table Query Structured Logs with JSON data SELECT TOP 10 Id ,JSON_VALUE([LogEvent], '$.Properties.SourceContext') AS [SourceContext] ,JSON_VALUE([LogEvent], '$.Properties.MachineName') AS MachineName ,JSON_VALUE([LogEvent], '$.Properties.EnvironmentUserName') AS EnvironmentUserName ,JSON_VALUE([LogEvent], '$.Properties.UserName') AS UserName ,[LogEvent], [Message] FROM [EventPortal].[dbo].[Logs] WHERE ISJSON([LogEvent]) > 0 AND JSON_VALUE([LogEvent], '$.Properties.UserName') = 'staff@msctek.com' ORDER BY JSON_VALUE([LogEvent], '$.TimeStamp') DESC