I am always amazed at the focus, and speed in which you are able to live code and explain, but what really is impressive is the amount of knowledge you have on aspnet at such a young age ;-)
Another way to go for plug-in based architecture is source-code-based-plugins where you load the source code of a plugin at run-time, compile it, and, the rest is very similar. If the source code changes, you re-compile the code for changes to take effect.
Thanks for this wonderful article. I have some queries. In this you loaded the assembly as hardcoded. How to achieve this for multiple plugins. For example, if I have employee, department, staff plugins and these need to load at runtime. How to achieve this. Also, is it possible to load the Web API Controllers in similar ways. Thanks.
What a great video I like the approach I think you should look for the plugin interface and what classes are implementing it in the assembly instead of the concrete class as you shouldn't know what is in the plugin yet I beleive most of the payment gateways plugins using similar approach
thanks, just writing a similar application and wondered why in the microsoft documentation they offer to inherit from the AssemblyLoadContext class for the sake of uncomplicated lines of code that is already in it and without me
This is good subject. I tried similar thing using ApplicationParts and Features. In you solution, how would you pass arguments from the DI container into your plugin? do you think it possible to initialize a custom DI container in the plugin from the main DI of the application?
Really good video, you clearly know your stuff. However, I don’t really understand what “leaking into global space” means. I was confused at the end with the serializer example and the WeakReference… why would you have to call GC 10 times…?
Global namespace was probably a bad choice of words. Think of the app that you start as the main assembly. If you add an assembly dynamically and then then something from the main assembly holds a reference to your dynamic one; the dynamic one will fail to unload. WeakReference is holding a reference from main to dynamic but doesn’t prevent unloading.
@@RawCoding Maybe something like saving a dump from a serverapp with executing a plugin method and replayi it with a plugin assembly? Maybe in the next video? :)
Thanks, great video like always, I was doing very similar this weekend and stumbled on the same error of not being able to unload my dll after serializing, both with newtonsoft and the microsoft one. I tried various third party and they all appear to hold a reference. Has anyone found one that doesn't stop us from unloading the plugin assembly?
@@RawCoding Good idea, but the problem i'm facing is that the service loading up and executing the plugin takes a json string as parameters and uses reflection to get the input parameter class type then creates and deserializes the input string to create that valuemodel class so the plugin creator can just work with his valuemodel directly. But to get this to work i'm using the newtonsoft serializer outside the plugin to deserialize a class defined inside the plugin :P
@@RawCoding I solved it today by asking chatgtp to write me a basic json serializer/deserializer that only relies on reflection. it was 250 lines of code but it worked for the project :)
An interesting video but I think trying to reload the plugin assemblies in-process is too fraught with pitfalls some of which this video highlights. Perhaps it would be better to just load the plugins at startup, registering the endpoints in the usual manner without custom middleware, and then have a separate process watch the plugin folder and spool up new instances of the web app, and use a reverse proxy to switch over, like you demonstrate in the 0 downtime deployment using YARP video.
it was really interesting, but in nopcommerce we only write plugins and install them without chnaging anything in main nopcpmments. So is it possible for u to help us understand this
@@RawCoding besides using interface vs concrete implementation for testability or no dependence on aspnet.core lib in the lower layer, I cannot think of anything else.
IHttpContextAccessor has HttpContext getter, I'd have to create a mock of HttpContext then configure the IHttpContextAccessor mock. Here I can just pass HttpContext directly so no testability advantage, as most of the time interfaces for "testability" and "decoupling" are bull shit.
Excelent Video Thank you, but i didint get from where took pathinfo their properties values for Method and path var pathInfo = endpointType?.GetCustomAttribute(); pathInfo.Method ¿From where took its value? pathInfo .path ¿from where took its value?
I am always amazed at the focus, and speed in which you are able to live code and explain, but what really is impressive is the amount of knowledge you have on aspnet at such a young age ;-)
yea. how do you know all this :/
Wow I learned a lot of technical things in this one video that I had never heard of or even thought about looking up in Docs. Thank you.
Another way to go for plug-in based architecture is source-code-based-plugins where you load the source code of a plugin at run-time, compile it, and, the rest is very similar. If the source code changes, you re-compile the code for changes to take effect.
Yea boi!
As always a beautiful video 👍
Anyway, if you want to define middleware you can just use the IMiddleware interface
Ah didn’t know
Late for party 😢
Thanks for this wonderful article. I have some queries. In this you loaded the assembly as hardcoded. How to achieve this for multiple plugins. For example, if I have employee, department, staff plugins and these need to load at runtime. How to achieve this.
Also, is it possible to load the Web API Controllers in similar ways.
Thanks.
I really like the microkernel architecture.
What a great video
I like the approach
I think you should look for the plugin interface and what classes are implementing it in the assembly instead of the concrete class as you shouldn't know what is in the plugin yet
I beleive most of the payment gateways plugins using similar approach
thanks, just writing a similar application and wondered why in the microsoft documentation they offer to inherit from the AssemblyLoadContext class for the sake of uncomplicated lines of code that is already in it and without me
As usual, your content blows me off Thanks !
This is good subject. I tried similar thing using ApplicationParts and Features. In you solution, how would you pass arguments from the DI container into your plugin? do you think it possible to initialize a custom DI container in the plugin from the main DI of the application?
which keyboard do you use? sounds good lol
Great content.
Can you load a plugin with dependencies that are of a different version than the main app?
I think it's possible yes
All of your videos are very cool, thank you!
love your stuff mate, really enjoying
Thank, that what i was looking for à long time!
Very nice topic, sir!
Wut is 'dotwatch' that you use in the terminal?
it's an alias for
dotnet watch --no-hot-reload
@@RawCoding Ah okey, thank you.
Thank you, great video!
Really good video, you clearly know your stuff. However, I don’t really understand what “leaking into global space” means. I was confused at the end with the serializer example and the WeakReference… why would you have to call GC 10 times…?
Global namespace was probably a bad choice of words.
Think of the app that you start as the main assembly. If you add an assembly dynamically and then then something from the main assembly holds a reference to your dynamic one; the dynamic one will fail to unload.
WeakReference is holding a reference from main to dynamic but doesn’t prevent unloading.
@@RawCoding thanks! Keep up the great content
Cool video!
What about plugin debugging?
What about it? :D test your plugin before you deploy it or use an ide that has a decompiler
@@RawCoding Maybe something like saving a dump from a serverapp with executing a plugin method and replayi it with a plugin assembly?
Maybe in the next video? :)
Great content, thank you
I'm sorry, I thought because of the title that this will be about c# plugins and not asp core plugins 😢 Great video though!
Ehh it’s the same thing
Thanks, great video like always, I was doing very similar this weekend and stumbled on the same error of not being able to unload my dll after serializing, both with newtonsoft and the microsoft one. I tried various third party and they all appear to hold a reference. Has anyone found one that doesn't stop us from unloading the plugin assembly?
you can trying doing serialisation outside of the plugin if possible
@@RawCoding Good idea, but the problem i'm facing is that the service loading up and executing the plugin takes a json string as parameters and uses reflection to get the input parameter class type then creates and deserializes the input string to create that valuemodel class so the plugin creator can just work with his valuemodel directly. But to get this to work i'm using the newtonsoft serializer outside the plugin to deserialize a class defined inside the plugin :P
mhmmm, from what I read there might a converter implementation that you have to substitute.
@@RawCoding I solved it today by asking chatgtp to write me a basic json serializer/deserializer that only relies on reflection. it was 250 lines of code but it worked for the project :)
Yes. Yessss!!!
thank you :)
Superb
An interesting video but I think trying to reload the plugin assemblies in-process is too fraught with pitfalls some of which this video highlights. Perhaps it would be better to just load the plugins at startup, registering the endpoints in the usual manner without custom middleware, and then have a separate process watch the plugin folder and spool up new instances of the web app, and use a reverse proxy to switch over, like you demonstrate in the 0 downtime deployment using YARP video.
All of that is viable both have their own pros and cons
Plug-ins being flaky is a .NET issue.
Good video!
Thank you
it was really interesting, but in nopcommerce we only write plugins and install them without chnaging anything in main nopcpmments. So is it possible for u to help us understand this
sorry I don't understand
Why use HttpContext instead of IContextAccessor?
what's the difference?
@@RawCoding besides using interface vs concrete implementation for testability or no dependence on aspnet.core lib in the lower layer, I cannot think of anything else.
IHttpContextAccessor has HttpContext getter, I'd have to create a mock of HttpContext then configure the IHttpContextAccessor mock. Here I can just pass HttpContext directly
so no testability advantage, as most of the time interfaces for "testability" and "decoupling" are bull shit.
This is too much voodoo
Excelent Video Thank you, but i didint get from where took pathinfo their properties values for Method and path
var pathInfo = endpointType?.GetCustomAttribute();
pathInfo.Method ¿From where took its value?
pathInfo .path ¿from where took its value?
it was from here right?
[Path("get", "/plugin/test")]
public class AnEndpoint : IPluginEndpont