website-hugo/content/posts/modular-web-app.md

66 lines
3.5 KiB
Markdown

+++
title = "Plugin-Based Web Application in Dotnet"
date = "2024-01-20T00:00:00+00:00"
author = "the1mason"
authorTwitter = "the0mason" #do not include @
cover = "posts/modular-app/title.svg"
tags = ["dotnet", "web", "prototype"]
keywords = ["prototype", "dotnet", "guide", "plugins", "plugin-based", "web application", "ASP.NET", "C#", ".NET 8", "Programming", "Software Architecture"]
description = "Have you ever thought about making a web application, that could be easily extended by third-party developers? I've been thinking about making this app for a while, so here's my experience..."
showFullContent = false
readingTime = true
hideComments = false
draft = true
+++
### Table of Contents
- [Introduction](#introduction)
- [Why](#why)
- [How](#how)
- [The Prototype](#the-prototype)
- - [IPlugin](#iplugin)
- - [Loading Plugins](#loading-plugins)
- - [Hooks and Triggers](#hooks-and-triggers)
- [Sources](#sources)
# Introduction
This post is about my experience of making a prototype of a web app with plugin support as well as my reasoning. As a result, this app could be extended by adding compiled `.dll` class libraries into a plugins folder. I've made it possible to load not only classes, but also views and api controllers. You could check out the final version of this prototype in this [GitHub Repo](//github.com/the1mason/prototype.modularmvc).
Also right now I'm building a web application, using similar concepts. As of now it's not on github, but you can find it [here](//git.the1mason.com/the1mason/octocore).
<script src="/js/repo-card.js"></script>
<div class="repo-card" data-repo="the1mason/Prototype.ModularMVC" data-theme="dark-theme"></div>
# Why
Self-hosted web applications can solve different problems and be of use for a variety of different people with slightly different needs. In order for this to work, I think that such application should provide an option to extend it's functionality. This would allow other people to build an ecosystem of different extensions.
# Stack
![C#, MVC, HTMX](/posts/modular-app/stack.svg)
Do you speak *CSharp*?
I do. It's my main language after all, but why MVC and what is HTMX?
Let's have a quick look at worthy alternatives, and then I'll explain my choices.
`Blazor WASM` does not support runtime assembly loading, which makes client extension impossible. It has [Lazy loading](https://learn.microsoft.com/en-us/aspnet/core/blazor/webassembly-lazy-load-assemblies?view=aspnetcore-8.0), but still it requires these assemblies to be defined in the project file, which is not viable for our case.
`WebApi + <name a JS framework>` is also not an option. It would require plugins to be written in two languages. Also client would have to be rebuilt after each plugin istallation.
So, what are MVC and HTMX?
`ASP.NET MVC` is an older framework that uses `Razor Pages` to render HTML on server and return it to the client. But it has a significant problem: Lack of reactivity. Each user's action would have to be processed on the server like in the good old days...
So in order for the app to be usable, I have decided to go with `HTMX`:
![Created With HTMX meme](/posts/modular-app/createdwith.jpeg)
> htmx gives you access to AJAX, CSS Transitions, WebSockets and Server Sent Events directly in HTML, using attributes, so you can build modern user interfaces with the simplicity and power of hypertext.
> *— from [htmx.org](htmx.org)*
This means, that I will use razor pages to generate an HTML body with HTMX tags, and return it to the client. The client would then read HTML, executing HTMX tags. Ain't that awesome?
# How
:)