+++
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 = false
+++

### 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 can 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 to a variety of different people with slightly different needs. For this to work, I think that such an application should provide an option to extend its 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 it still 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, the client would have to be rebuilt after each plugin installation.

So, what are MVC and HTMX?

`ASP.NET MVC` is an older framework that uses `Razor Pages` to render HTML on a 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`:

> 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)*

<div style="display: flex; justify-content: center">
    <img src="/posts/modular-app/createdwith.jpeg" style="height: 50px;"/>
</div>
<br>

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

[This](https://learn.microsoft.com/en-us/dotnet/core/tutorials/creating-app-with-plugin-support) article gives the base for plugin loading. It doesn't cover the ASP.NET part but otherwise is very helpful.  
Still, I will explain basic concepts here. Just to have everything in one place.  


