Share razor library between blazor wasm and .net maui blazor project – (2/2)

Published Oct 11, 2022 | Updated Oct 12, 2022 | 0 comments

Blazor WebAssembly 환경으로 이미 개발된 서비스가 있는 경우 .Net MAUI 를 사용해서 모바일 및 더 많은 환경을 지원하기 위해 추가 개발을 하는 경우
이미 작성된 razor 페이지 또는 라이브러리를 재활용하기 위한 샘플 소스를 만들어 보겠습니다.

1부 – https://blog.kkomzi.net/26405

새 솔루션과 Blazor WebAssembly 형식의 프로젝트를 생성한 다음 기본 템플릿을 그대로 사용합니다.
RCL(Razor class library) 프로젝트를 추가한 다음 공유할 항목들을 RCL 프로젝트로 이동해서 참조하게 수정합니다.

2부 – https://blog.kkomzi.net/26442

.Net MAUI Blazor 프로젝트를 추가한 다음 RCL 프로젝트를 참조해서 동일한 UI 를 구성해 보겠습니다.

참고로 Visual studio 2022 가 7.3 버전부터 MAUI 를 공식 지원하게 되면서 해당 버전 이후로 업데이트를 하게 되면 Preview 버전을 굳이 설치하지 않아도 된다고 합니다.

Visual Studio 2022 17.3 is now available! – Visual Studio Blog (microsoft.com)

.Net MAUI Blazor 프로젝트 추가

MauiAppBlazor 프로젝트를 다시 빌드 하신 다음 Windows Machine 플랫폼으로 실행해 보면 다음과 같이 Blazor WebAssembly 의 기본 템플릿과 동일한 UI 로 실행이 됩니다.

MauiAppBlazor 프로젝트에서 RCL 프로젝트의 페이지를 참조하게 수정

MauiAppBlazor 프로젝트에서 불필요한 항목들을 삭제합니다.

MauiAppBlazor 프로젝트에서 Data, Pages, Shared 폴더를 삭제합니다.
MauiAppBlazor 프로젝트에서 wwwroot 폴더 하위의 항목 중에서 index.html 을 제외하고 모두 삭제합니다.

MauiAppBlazor 프로젝트에 RCL 프로젝트를 프로젝트 참조로 추가합니다.

그러면 다음과 같이 플랫폼 별로 프로젝트 참조가 추가된 것을 확인하실 수 있습니다.

MauiAppBlazor 프로젝트의 _Imports.razor 파일을 수정합니다.

@using System.Net.Http
@using Microsoft.AspNetCore.Components.Forms
@using Microsoft.AspNetCore.Components.Routing
@using Microsoft.AspNetCore.Components.Web
@using Microsoft.AspNetCore.Components.Web.Virtualization
@using Microsoft.JSInterop
@using MauiAppBlazor
@using RazorClassLibrary.Shared

MauiAppBlazor 프로젝트의 Main.razor 파일을 수정합니다.

AdditionalAssemblies=”new[] { typeof(MainLayout).Assembly}” 항목을 추가하였습니다

<Router AppAssembly="@typeof(Main).Assembly" AdditionalAssemblies="new[] { typeof(MainLayout).Assembly}">
	<Found Context="routeData">
		<RouteView RouteData="@routeData" DefaultLayout="@typeof(MainLayout)" />
        <FocusOnNavigate RouteData="@routeData" Selector="h1" />
	</Found>
	<NotFound>
		<LayoutView Layout="@typeof(MainLayout)">
			<p role="alert">Sorry, there's nothing at this address.</p>
		</LayoutView>
	</NotFound>
</Router>

MauiAppBlazor 프로젝트의 index.html 파일을 수정합니다.

<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="utf-8" />
	<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no, viewport-fit=cover" />
	<title>MauiAppBlazor</title>
	<base href="/" />

	<link rel="icon" type="image/x-icon" href="_content/RazorClassLibrary/favicon.ico">
	<link href="_content/RazorClassLibrary/css/bootstrap/bootstrap.min.css" rel="stylesheet" />
	<link href="_content/RazorClassLibrary/css/app.css" rel="stylesheet" />
	<link href="MauiAppBlazor.styles.css" rel="stylesheet" />
</head>

<body>

	<div class="status-bar-safe-area"></div>

	<div id="app">Loading...</div>

	<div id="blazor-error-ui">
		An unhandled error has occurred.
		<a href="" class="reload">Reload</a>
		<a class="dismiss">🗙</a>
	</div>

	<script src="_framework/blazor.webview.js" autostart="false"></script>

</body>

</html>

WeatherForecastService 서비스 추가

FetchData 페이지에서 데이터를 조회하는 로직을 별도 서비스를 추가해서 공용으로 사용해 보겠습니다.

RCL 프로젝트에 Services 폴더를 생성 후 WeatherForecastService 를 추가합니다.

using BlazorWasm.Shared;

namespace RazorClassLibrary.Services
{
    public class WeatherForecastService
    {
        private static readonly string[] Summaries = new[]
        {
            "Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching"
        };

        public Task<WeatherForecast[]> GetForecastAsync(DateTime startDate)
        {
            return Task.FromResult(Enumerable.Range(1, 5).Select(index => new WeatherForecast
            {
                Date = startDate.AddDays(index),
                TemperatureC = Random.Shared.Next(-20, 55),
                Summary = Summaries[Random.Shared.Next(Summaries.Length)]
            }).ToArray());
        }
    }
}

MauiAppBlazor 프로젝트의 MauiProgram.cs 에서 서비스를 등록합니다.

using RazorClassLibrary.Services;

namespace MauiAppBlazor
{
    public static class MauiProgram
    {
        public static MauiApp CreateMauiApp()
        {
            var builder = MauiApp.CreateBuilder();
            builder
                .UseMauiApp<App>()
                .ConfigureFonts(fonts =>
                {
                    fonts.AddFont("OpenSans-Regular.ttf", "OpenSansRegular");
                });

            builder.Services.AddMauiBlazorWebView();
#if DEBUG
		builder.Services.AddBlazorWebViewDeveloperTools();
#endif
            builder.Services.AddSingleton<WeatherForecastService>();

            return builder.Build();
        }
    }
}

BlazorWasm.Client 프로젝트의 Program.cs 에서도 동일한 서비스를 등록합니다.

using BlazorWasm.Client;

using Microsoft.AspNetCore.Components.Web;
using Microsoft.AspNetCore.Components.WebAssembly.Hosting;

using RazorClassLibrary.Services;

namespace BlazorWasm.Client
{
    public class Program
    {
        public static async Task Main(string[] args)
        {
            var builder = WebAssemblyHostBuilder.CreateDefault(args);
            builder.RootComponents.Add<App>("#app");
            builder.RootComponents.Add<HeadOutlet>("head::after");

            builder.Services.AddScoped(sp => new HttpClient { BaseAddress = new Uri(builder.HostEnvironment.BaseAddress) });

            builder.Services.AddSingleton<WeatherForecastService>();

            await builder.Build().RunAsync();
        }
    }
}

RCL 프로젝트의 FetchData.razor 파일을 수정합니다.

@page "/fetchdata"

@inject WeatherForecastService WeatherForecast

@using RazorClassLibrary.Services

<PageTitle>Weather forecast</PageTitle>

<h1>Weather forecast</h1>

<p>This component demonstrates fetching data from the server.</p>

@if (forecasts == null)
{
    <p><em>Loading...</em></p>
}
else
{
    <table class="table">
        <thead>
            <tr>
                <th>Date</th>
                <th>Temp. (C)</th>
                <th>Temp. (F)</th>
                <th>Summary</th>
            </tr>
        </thead>
        <tbody>
            @foreach (var forecast in forecasts)
            {
                <tr>
                    <td>@forecast.Date.ToShortDateString()</td>
                    <td>@forecast.TemperatureC</td>
                    <td>@forecast.TemperatureF</td>
                    <td>@forecast.Summary</td>
                </tr>
            }
        </tbody>
    </table>
}

@code {
    private WeatherForecast[]? forecasts;

    protected override async Task OnInitializedAsync()
    {
		forecasts = await WeatherForecast.GetForecastAsync(DateTime.Now);
    }
}

정상동작 확인

Windows Machine
Android Emulators

Learn more on this topic

Related Blog Posts

C# 으로 사용자 입력을 받아 동작하는 콘솔 프로그램 구현

C# 으로 사용자 입력을 받아 동작하는 콘솔 프로그램 구현

네이버 지식인에서 우연히 보게 된 누군가의 질문... c# 콘솔 형태의 프로그램이며, 일정 갯수의 숫자를 데이터로 입력 받아 최대값/최소값 등을 구하거나 종료할 수 있는 기능을 하는 프로그램이 요구사항 이었다 내가 답변한 원문은 여기 : C# 프로그래밍 질문 : 지식iN (naver.com)네이버 지식인 링크 실제 프로그램이 실행되는 스크린샷은 다음 이미지와 같습니다. 프로그램이 실행되면 메뉴 설명을 출력합니다. 메뉴 선택에서 0~3 까지 숫자를 입력 받아 메뉴 선택의 용도로...

read more
Blazor bootstrap theme sample

Blazor bootstrap theme sample

전체 소스 코드는 다음 Github 의 BlazorBootswatchTheme 폴더에 있습니다 .net 으로 생성된 blazor wasm 기본 템플릿은 bootstrap 을 기반으로 하고 있습니다. 그리고 bootstratp 을 기반으로 다양한 테마를 제공하는 bootswatch 오픈소스 프로젝트가 있습니다. MIT 라이센스이며 다양한 테마가 존재합니다. 다양한 테마 목록은 여기(https://bootswatch.com/)를 클릭해서 확인해 보시기 바랍니다. 현재...

read more

Join in the conversation

Leave a Comment

0 Comments

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.

cloud app service

전광판

텍스트를 입력하고 텍스트 효과 및 배경효과 를 변경해서 전체화면으로 표시할 수 있는 전광판 용도로 사용하실 수 있습니다. 각종 스포츠 및 공연 관람시 응원 용도로 사용이 가능합니다.

Carousel

여러개의 슬라이드를 추가하여 프레젠테이션 및 이미지 슬라이드 용도로 사용하실 수 있습니다. 브라우저가 포함된 IT 기기로 큰 모니터에 연결하여 매장 내 공지사항 및 메뉴소개를 이미지로 표시할 수 있습니다.

타이머

지정된 시간이 경과한 후 소리로 알려주는 타이머 기능을 하고 있습니다.

Pin It on Pinterest

Shares
Share This

Share This

Share this post with your friends!

Shares