SlideShare a Scribd company logo
1 of 21
BlazorでCodeer.LowCode作った話
Blazorで NoCode/LowCode/ProCodeライブラリ作ってみた
石川達也
Codeer代表取締役
→社員募集中
プログラマ(C, C++, C#)
テスト自動化ライブラリ/ツール開発
Microsoft MVP 2014~
趣味はギターとOSSライブラリ作成
Twitter: @StoneGuitar777
自己紹介
ギターが趣味です
同じ趣味の人はブリ食べながら語りましょう!
Codeer.LowCode
https://codeerwebsite.azurewebsites.net/LowCode
ノー/ローコードとフルスクラッチのいいとこどり!
あなたのWebアプリをノー/ローコードアプリにするためのフレームワークです!
詳細はこちら
(2024年2月末リリース予定)
Codeer.LowCode
Blaozrで作ったライブラリです。
VisualStudioでプロジェクトを新規作成することで
Codeer.LowCodeを参照するアプリの
テンプレートで作成されます。
テンプレートコード
Codeer.LowCode.dll
認証機能やDBのコネクションの取得などは
こちらに作成されている
カスタマイズ可能
オリジナルのフィールドも追加可能
Codeer.LowCode
デモ
Blazorのいいところ
メリットとして C# で書いてると処理を抜き出しやすいので
大部分を一般的なC#のコードで書ける
結局昔から言われているようにホントのViewの部分は薄くつくるのが一番
NumberFieldComponent
NumberField(VM)
ロジックとかはこっちにある
スクリプトでもこちらを操作
Blazorをあまりかかなくてよい!
@if (IsViewMode == true) <span … />
else <input …/>
@code {
[Parameter]
public NumberField? Field { get; set; }
protected override void OnParametersSet()
{
base.OnParametersSet();
Field?.SetStateChangedReciver(StateHasChanged);
}
…
}
public virtual async Task SetValue(T? value)
{
if (IsSame(Current.Value, value)) return;
Current.Value = value;
await ExecuteOnDataChanged();
await NotifyDataChanged();
}
public void NotifyStateChanged() => _notfyStateChange();
UI
VM
ViewModel的なクラスを作成
WPFのINotifyPropertyChangedのイメージ
DynamicComponent
設定によってコンポーネントを切り替える
<DynamicComponent Type="@field.GetPresenterType()"
Parameters="GetPresenterParameters(design)"/>
DynamicComponent
public class DynamicComponent
{
public Type Field? SetStateChangedReciver { get; set; }
public IDictionary<string, object>? Parameters { get; set; }
…
}
Typeはイメージ的には同一の抽象クラスからの派生
パラメータはvirtualなプロパティ
@if (IsViewMode == true) <span … />
else <input …/>
@code {
[Parameter]
public FieldBase? Field { get; set; }
[Parameter]
public FieldDesignBase? Design { get; set; }
protected override void OnParametersSet()
{
base.OnParametersSet();
Field?.SetStateChangedReciver(StateHasChanged);
}
…
}
Dictionary<string, object?> GetPresenterParameters(FieldDesignBase design)
{
var parameters = new Dictionary<string, object?>();
parameters["Design"] = design;
parameters["Field"] = design.CreateField();
return parameters;
}
WPF+Blazor
Microsoft.AspNetCore.Components.WebView.Wpf
周りはWPFで
この部分だけBlazor
<blazor:BlazorWebView
Focusable ="True"
x:Name="BlazorWebViewElement"
HostPage="wwwroot/index.html"
Services="{StaticResource services}">
<blazor:BlazorWebView.RootComponents>
<blazor:RootComponent ComponentType="{x:Type tabs:FormLayoutDesigner}" Selector="#app" />
</blazor:BlazorWebView.RootComponents>
</blazor:BlazorWebView>
Xaml
var services = new ServiceCollection();
services.AddWpfBlazorWebView();
services.AddSingleton<BlazorComponentManager>();
Resources.Add("services", services.BuildServiceProvider());
@inject BlzorComponentManager BlazorComponentManager
…
protected override async Task OnInitializedAsync() {
await base.OnInitializedAsync();
//逆にBlazorのオブジェクトをWPFからアクセスできるようにしておく
BlazorComponentManager.FormLayoutDesigners[Design?.Name ?? string.Empty] = this;
}
DIでオブジェクトをやり取り
ServiceCollection
BlazorのComponentの型
WPF部分とBlazor部分の通信
パラメータでオブジェクトを渡す
public FormLayoutControl()
{
BlazorWebViewElement.RootComponents[0].Parameters = new Dictionary<string, object?>
{
["UpdateValue"] = Guid.NewGuid(),
["DesignAndScript"] = ViewModel.GetForm(name),
["FormDesigns"] = ViewModel.GetForms().Select(e => e.Design).ToArray()
};
}
[Parameter]
public FormDesign[] FormDesigns { get; set; } = Array.Empty<FormDesign>();
[Parameter]
public FormDesignAndScript? DesignAndScript { get; set; }
[Parameter]
public Guid UpdateValue { get; set; }
WPF
Blazor
WebViewer 備考
デバッグ楽
Publishハマった
かずきさん、
ありがとうございました!
WebViewer 備考
WebViewerってか
.NET系のデスクトップアプリ全般だけど・・・
Script
BlazorではRoslynのコード解析はできるけどコード実行はできない
//実行できないよ
var value = await CSharpScript.EvaluateAsync<int>("return 100;");
位置が指定されていないアセンブリのメタデータ参照を作成できません。
とにかく無理らしい
Formをクラスみたいにnewしたいとか
Fieldをプロパティ的に扱いたい
というのもあったので
Script
解析はできるので後はそれを見ながら実行(力業)
Jsonのポリモフィズム
public abstract class JsonAbstract
{
public string TypeFullName { get; set; } = string.Empty;
protected JsonAbstract(string typeFullName)
=> TypeFullName = typeFullName;
}
public class TextFieldDesign : ValueFieldDesignBase
{
public TextFieldDesign() : base(typeof(TextFieldDesign).FullName!) { }
…
}
TypeFullNameを持っておく
public class FormDesign
{
public List<FieldDesignBase> Fields { get; set; } = new();
}
これをJsonに保存したい
public class JsonAbstractClassConverter<T> : JsonConverter<T> where T : JsonAbstract
{
public override T Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
using JsonDocument document = JsonDocument.ParseValue(ref reader);
if (!document.RootElement.TryGetProperty("TypeFullName", out JsonElement typeProperty) &&
!document.RootElement.TryGetProperty("typeFullName", out typeProperty))
throw new JsonException("TypeFullName property is missing.");
var typeFullName = typeProperty.GetString() ?? string.Empty;
var type = TypeFinder.GetType(typeFullName);
if (type == null || !typeof(T).IsAssignableFrom(type))
throw new JsonException($"Type {typeFullName} is not a valid {typeof(T)} type.");
var deserializeMethod = typeof(JsonSerializer).
GetMethod("Deserialize", new[] { typeof(JsonElement), typeof(JsonSerializerOptions) })!.MakeGenericMethod(type);
var obj = deserializeMethod.Invoke(null, new object[] { document.RootElement, options });
return (T)obj!;
}
public override void Write(Utf8JsonWriter writer, T value, JsonSerializerOptions options)
=> JsonSerializer.Serialize(writer, (object)value, options);
}
Jsonのポリモフィズム
public static void AddJsonConverters(this IList<JsonConverter> Converters)
{
Converters.Add(new JsonAbstractClassConverter<JsonAbstract>());
foreach (var e in GetJsonAbstracts())
{
Converters.Add((JsonConverter)Activator.CreateInstance(typeof(JsonAbstractClassConverter<>).MakeGenericType(e))!);
}
}
static List<Type> GetJsonAbstracts()
{
var assemblies = AppDomain.CurrentDomain.GetAssemblies();
var fieldDesigns = new List<Type>();
foreach (var assembly in assemblies)
{
var types = assembly.GetTypes();
fieldDesigns.AddRange(types.Where(t => t.IsClass && !t.IsGenericType &&
t.IsAbstract && t.IsSubclassOf(typeof(JsonAbstract))));
}
return fieldDesigns;
}
Jsonのポリモフィズム
ClosedXmlとPDFSharp
フロントで動く
(System.Drawaing.Commonの依存がなくなってた)
var searchFile = new FormSearcher("TestFiles");
searchFile.AddEquals("Name.Value", "Quotation");
var file = searchFile.Execute()[0];
var excel = file.File.GetExcel();
excel.OverWrite(this);
excel.DownloadPdf();
フロントでスクリプト内で動いている
※でもフォント配布の問題とかあって
サーバーサイド実行に変えるかも

More Related Content

Similar to burikaigi2024.pptx

Djangoフレームワークの紹介
Djangoフレームワークの紹介Djangoフレームワークの紹介
Djangoフレームワークの紹介Shinya Okano
 
OSSから学ぶSwift実践テクニック
OSSから学ぶSwift実践テクニックOSSから学ぶSwift実践テクニック
OSSから学ぶSwift実践テクニック庸介 高橋
 
Djangoフレームワークの紹介
Djangoフレームワークの紹介Djangoフレームワークの紹介
Djangoフレームワークの紹介Shinya Okano
 
Mongo db使ってみよう
Mongo db使ってみようMongo db使ってみよう
Mongo db使ってみようOda Shinsuke
 
"今" 押さえておきたい! Web アプリ開発の技術トレンドとツールの進化
"今" 押さえておきたい! Web アプリ開発の技術トレンドとツールの進化"今" 押さえておきたい! Web アプリ開発の技術トレンドとツールの進化
"今" 押さえておきたい! Web アプリ開発の技術トレンドとツールの進化Akira Inoue
 
TypeScript 1.0 オーバービュー
TypeScript 1.0 オーバービューTypeScript 1.0 オーバービュー
TypeScript 1.0 オーバービューAkira Inoue
 
Firefox DevTools
Firefox DevToolsFirefox DevTools
Firefox DevToolsdynamis
 
Elasticsearchプラグインの作り方
Elasticsearchプラグインの作り方Elasticsearchプラグインの作り方
Elasticsearchプラグインの作り方Shinsuke Sugaya
 
.NETの自作ツール公開手段
.NETの自作ツール公開手段.NETの自作ツール公開手段
.NETの自作ツール公開手段Pierre3 小林
 
Go言語入門者が Webアプリケーション を作ってみた話 #devfest #gdgkyoto
Go言語入門者が Webアプリケーション を作ってみた話 #devfest #gdgkyotoGo言語入門者が Webアプリケーション を作ってみた話 #devfest #gdgkyoto
Go言語入門者が Webアプリケーション を作ってみた話 #devfest #gdgkyotoShoot Morii
 
cloud_firestore_schema_code_generation_for_flutter.pdf
cloud_firestore_schema_code_generation_for_flutter.pdfcloud_firestore_schema_code_generation_for_flutter.pdf
cloud_firestore_schema_code_generation_for_flutter.pdfKosuke Saigusa
 
DEV-010_エンプラ系業務 Web アプリ開発に効く! 実践的 SPA 型モダン Web アプリ開発の選択手法
DEV-010_エンプラ系業務 Web アプリ開発に効く! 実践的 SPA 型モダン Web アプリ開発の選択手法DEV-010_エンプラ系業務 Web アプリ開発に効く! 実践的 SPA 型モダン Web アプリ開発の選択手法
DEV-010_エンプラ系業務 Web アプリ開発に効く! 実践的 SPA 型モダン Web アプリ開発の選択手法decode2016
 
GoF デザインパターン 2009
GoF デザインパターン 2009GoF デザインパターン 2009
GoF デザインパターン 2009miwarin
 
WebIDLを見てみる
WebIDLを見てみるWebIDLを見てみる
WebIDLを見てみるtakenspc
 
Unity C#3からC#6に向けて
Unity C#3からC#6に向けてUnity C#3からC#6に向けて
Unity C#3からC#6に向けてonotchi_
 
What, Why, How Create OSS Libraries - 過去に制作した30のライブラリから見るC#コーディングテクニックと個人OSSの...
What, Why, How Create OSS Libraries - 過去に制作した30のライブラリから見るC#コーディングテクニックと個人OSSの...What, Why, How Create OSS Libraries - 過去に制作した30のライブラリから見るC#コーディングテクニックと個人OSSの...
What, Why, How Create OSS Libraries - 過去に制作した30のライブラリから見るC#コーディングテクニックと個人OSSの...Yoshifumi Kawai
 
CodeIgniterによるPhwittr
CodeIgniterによるPhwittrCodeIgniterによるPhwittr
CodeIgniterによるPhwittrkenjis
 
IdrisでWebアプリを書く
IdrisでWebアプリを書くIdrisでWebアプリを書く
IdrisでWebアプリを書くHideyuki Tanaka
 
D3js入門 - Code for Kobe 可視化勉強会資料
D3js入門 - Code for Kobe 可視化勉強会資料D3js入門 - Code for Kobe 可視化勉強会資料
D3js入門 - Code for Kobe 可視化勉強会資料充彦 保田
 
13016 n分で作るtype scriptでnodejs
13016 n分で作るtype scriptでnodejs13016 n分で作るtype scriptでnodejs
13016 n分で作るtype scriptでnodejsTakayoshi Tanaka
 

Similar to burikaigi2024.pptx (20)

Djangoフレームワークの紹介
Djangoフレームワークの紹介Djangoフレームワークの紹介
Djangoフレームワークの紹介
 
OSSから学ぶSwift実践テクニック
OSSから学ぶSwift実践テクニックOSSから学ぶSwift実践テクニック
OSSから学ぶSwift実践テクニック
 
Djangoフレームワークの紹介
Djangoフレームワークの紹介Djangoフレームワークの紹介
Djangoフレームワークの紹介
 
Mongo db使ってみよう
Mongo db使ってみようMongo db使ってみよう
Mongo db使ってみよう
 
"今" 押さえておきたい! Web アプリ開発の技術トレンドとツールの進化
"今" 押さえておきたい! Web アプリ開発の技術トレンドとツールの進化"今" 押さえておきたい! Web アプリ開発の技術トレンドとツールの進化
"今" 押さえておきたい! Web アプリ開発の技術トレンドとツールの進化
 
TypeScript 1.0 オーバービュー
TypeScript 1.0 オーバービューTypeScript 1.0 オーバービュー
TypeScript 1.0 オーバービュー
 
Firefox DevTools
Firefox DevToolsFirefox DevTools
Firefox DevTools
 
Elasticsearchプラグインの作り方
Elasticsearchプラグインの作り方Elasticsearchプラグインの作り方
Elasticsearchプラグインの作り方
 
.NETの自作ツール公開手段
.NETの自作ツール公開手段.NETの自作ツール公開手段
.NETの自作ツール公開手段
 
Go言語入門者が Webアプリケーション を作ってみた話 #devfest #gdgkyoto
Go言語入門者が Webアプリケーション を作ってみた話 #devfest #gdgkyotoGo言語入門者が Webアプリケーション を作ってみた話 #devfest #gdgkyoto
Go言語入門者が Webアプリケーション を作ってみた話 #devfest #gdgkyoto
 
cloud_firestore_schema_code_generation_for_flutter.pdf
cloud_firestore_schema_code_generation_for_flutter.pdfcloud_firestore_schema_code_generation_for_flutter.pdf
cloud_firestore_schema_code_generation_for_flutter.pdf
 
DEV-010_エンプラ系業務 Web アプリ開発に効く! 実践的 SPA 型モダン Web アプリ開発の選択手法
DEV-010_エンプラ系業務 Web アプリ開発に効く! 実践的 SPA 型モダン Web アプリ開発の選択手法DEV-010_エンプラ系業務 Web アプリ開発に効く! 実践的 SPA 型モダン Web アプリ開発の選択手法
DEV-010_エンプラ系業務 Web アプリ開発に効く! 実践的 SPA 型モダン Web アプリ開発の選択手法
 
GoF デザインパターン 2009
GoF デザインパターン 2009GoF デザインパターン 2009
GoF デザインパターン 2009
 
WebIDLを見てみる
WebIDLを見てみるWebIDLを見てみる
WebIDLを見てみる
 
Unity C#3からC#6に向けて
Unity C#3からC#6に向けてUnity C#3からC#6に向けて
Unity C#3からC#6に向けて
 
What, Why, How Create OSS Libraries - 過去に制作した30のライブラリから見るC#コーディングテクニックと個人OSSの...
What, Why, How Create OSS Libraries - 過去に制作した30のライブラリから見るC#コーディングテクニックと個人OSSの...What, Why, How Create OSS Libraries - 過去に制作した30のライブラリから見るC#コーディングテクニックと個人OSSの...
What, Why, How Create OSS Libraries - 過去に制作した30のライブラリから見るC#コーディングテクニックと個人OSSの...
 
CodeIgniterによるPhwittr
CodeIgniterによるPhwittrCodeIgniterによるPhwittr
CodeIgniterによるPhwittr
 
IdrisでWebアプリを書く
IdrisでWebアプリを書くIdrisでWebアプリを書く
IdrisでWebアプリを書く
 
D3js入門 - Code for Kobe 可視化勉強会資料
D3js入門 - Code for Kobe 可視化勉強会資料D3js入門 - Code for Kobe 可視化勉強会資料
D3js入門 - Code for Kobe 可視化勉強会資料
 
13016 n分で作るtype scriptでnodejs
13016 n分で作るtype scriptでnodejs13016 n分で作るtype scriptでnodejs
13016 n分で作るtype scriptでnodejs
 

More from Tatsuya Ishikawa

【オンライン】.NET 6 移行祭り! C# Tokyo イベント
【オンライン】.NET 6 移行祭り! C# Tokyo イベント【オンライン】.NET 6 移行祭り! C# Tokyo イベント
【オンライン】.NET 6 移行祭り! C# Tokyo イベントTatsuya Ishikawa
 
Test automation strategy for .net core 3 transition
Test automation strategy for .net core 3 transitionTest automation strategy for .net core 3 transition
Test automation strategy for .net core 3 transitionTatsuya Ishikawa
 
Infragistics Web Day 2017 - 継続的な開発を支える テスト自動化技術
Infragistics Web Day 2017 - 継続的な開発を支える テスト自動化技術Infragistics Web Day 2017 - 継続的な開発を支える テスト自動化技術
Infragistics Web Day 2017 - 継続的な開発を支える テスト自動化技術Tatsuya Ishikawa
 
Stack2017 自動化困難な状況での活動方法
Stack2017 自動化困難な状況での活動方法Stack2017 自動化困難な状況での活動方法
Stack2017 自動化困難な状況での活動方法Tatsuya Ishikawa
 
メタな感じのプログラミング(プロ生 + わんくま 071118)
メタな感じのプログラミング(プロ生 + わんくま 071118)メタな感じのプログラミング(プロ生 + わんくま 071118)
メタな感じのプログラミング(プロ生 + わんくま 071118)Tatsuya Ishikawa
 
Dot netconf2017 - VS拡張
Dot netconf2017 - VS拡張Dot netconf2017 - VS拡張
Dot netconf2017 - VS拡張Tatsuya Ishikawa
 
価値あるシステムテスト自動化の実現By friendly
価値あるシステムテスト自動化の実現By friendly価値あるシステムテスト自動化の実現By friendly
価値あるシステムテスト自動化の実現By friendlyTatsuya Ishikawa
 
Bindingからframework elementを見つける
Bindingからframework elementを見つけるBindingからframework elementを見つける
Bindingからframework elementを見つけるTatsuya Ishikawa
 
【SQiP2014】システム操作インターフェイス最適化によるテスト自動化ROI向上
【SQiP2014】システム操作インターフェイス最適化によるテスト自動化ROI向上【SQiP2014】システム操作インターフェイス最適化によるテスト自動化ROI向上
【SQiP2014】システム操作インターフェイス最適化によるテスト自動化ROI向上Tatsuya Ishikawa
 
Friendlyで始めるwindowsアプリシステムテスト自動化+内部使用技術解説
Friendlyで始めるwindowsアプリシステムテスト自動化+内部使用技術解説Friendlyで始めるwindowsアプリシステムテスト自動化+内部使用技術解説
Friendlyで始めるwindowsアプリシステムテスト自動化+内部使用技術解説Tatsuya Ishikawa
 
Windowsアプリテスト自動化 [Friendly+delphi]
Windowsアプリテスト自動化 [Friendly+delphi]Windowsアプリテスト自動化 [Friendly+delphi]
Windowsアプリテスト自動化 [Friendly+delphi]Tatsuya Ishikawa
 
Ride on azure~アイデアソン編~
Ride on azure~アイデアソン編~Ride on azure~アイデアソン編~
Ride on azure~アイデアソン編~Tatsuya Ishikawa
 
私とC++ in 例外安全day
私とC++ in 例外安全day私とC++ in 例外安全day
私とC++ in 例外安全dayTatsuya Ishikawa
 
他言語との連携(ネイティブから動的言語まで)
他言語との連携(ネイティブから動的言語まで)他言語との連携(ネイティブから動的言語まで)
他言語との連携(ネイティブから動的言語まで)Tatsuya Ishikawa
 

More from Tatsuya Ishikawa (20)

【オンライン】.NET 6 移行祭り! C# Tokyo イベント
【オンライン】.NET 6 移行祭り! C# Tokyo イベント【オンライン】.NET 6 移行祭り! C# Tokyo イベント
【オンライン】.NET 6 移行祭り! C# Tokyo イベント
 
burikaigi2023
burikaigi2023burikaigi2023
burikaigi2023
 
Test to net core 3
Test to net core 3Test to net core 3
Test to net core 3
 
Test automation strategy for .net core 3 transition
Test automation strategy for .net core 3 transitionTest automation strategy for .net core 3 transition
Test automation strategy for .net core 3 transition
 
Developer summit codeer
Developer summit codeerDeveloper summit codeer
Developer summit codeer
 
Infragistics Web Day 2017 - 継続的な開発を支える テスト自動化技術
Infragistics Web Day 2017 - 継続的な開発を支える テスト自動化技術Infragistics Web Day 2017 - 継続的な開発を支える テスト自動化技術
Infragistics Web Day 2017 - 継続的な開発を支える テスト自動化技術
 
Stack2017 自動化困難な状況での活動方法
Stack2017 自動化困難な状況での活動方法Stack2017 自動化困難な状況での活動方法
Stack2017 自動化困難な状況での活動方法
 
メタな感じのプログラミング(プロ生 + わんくま 071118)
メタな感じのプログラミング(プロ生 + わんくま 071118)メタな感じのプログラミング(プロ生 + わんくま 071118)
メタな感じのプログラミング(プロ生 + わんくま 071118)
 
Dot netconf2017 - VS拡張
Dot netconf2017 - VS拡張Dot netconf2017 - VS拡張
Dot netconf2017 - VS拡張
 
.Netconf
.Netconf.Netconf
.Netconf
 
価値あるシステムテスト自動化の実現By friendly
価値あるシステムテスト自動化の実現By friendly価値あるシステムテスト自動化の実現By friendly
価値あるシステムテスト自動化の実現By friendly
 
Stac2014 石川
Stac2014 石川Stac2014 石川
Stac2014 石川
 
Bindingからframework elementを見つける
Bindingからframework elementを見つけるBindingからframework elementを見つける
Bindingからframework elementを見つける
 
boost - std - C#
boost - std - C#boost - std - C#
boost - std - C#
 
【SQiP2014】システム操作インターフェイス最適化によるテスト自動化ROI向上
【SQiP2014】システム操作インターフェイス最適化によるテスト自動化ROI向上【SQiP2014】システム操作インターフェイス最適化によるテスト自動化ROI向上
【SQiP2014】システム操作インターフェイス最適化によるテスト自動化ROI向上
 
Friendlyで始めるwindowsアプリシステムテスト自動化+内部使用技術解説
Friendlyで始めるwindowsアプリシステムテスト自動化+内部使用技術解説Friendlyで始めるwindowsアプリシステムテスト自動化+内部使用技術解説
Friendlyで始めるwindowsアプリシステムテスト自動化+内部使用技術解説
 
Windowsアプリテスト自動化 [Friendly+delphi]
Windowsアプリテスト自動化 [Friendly+delphi]Windowsアプリテスト自動化 [Friendly+delphi]
Windowsアプリテスト自動化 [Friendly+delphi]
 
Ride on azure~アイデアソン編~
Ride on azure~アイデアソン編~Ride on azure~アイデアソン編~
Ride on azure~アイデアソン編~
 
私とC++ in 例外安全day
私とC++ in 例外安全day私とC++ in 例外安全day
私とC++ in 例外安全day
 
他言語との連携(ネイティブから動的言語まで)
他言語との連携(ネイティブから動的言語まで)他言語との連携(ネイティブから動的言語まで)
他言語との連携(ネイティブから動的言語まで)
 

burikaigi2024.pptx