Hack Forums
[.NET] Adding a new class dynamically on the fly ? - Printable Version

+- Hack Forums (https://hackforums.net)
+-- Forum: Tech (https://hackforums.net/forumdisplay.php?fid=444)
+--- Forum: Coding (https://hackforums.net/forumdisplay.php?fid=151)
+---- Forum: Software Development (https://hackforums.net/forumdisplay.php?fid=118)
+---- Thread: [.NET] Adding a new class dynamically on the fly ? (/showthread.php?tid=5936846)

Pages: Pages 1 2


Adding a new class dynamically on the fly ? - System[X] - Feb 2, 2019

Hi all, im in need of a little assistance.

What i need to do is add a new class to my app after its been compiled.

I have read about CodeDOM and Reflection. Both see to be able to do this but i cant seem to find codes in vb.net that show how to add a class.

Many code with codedom to create a new .exe file from code thats generated from the first exe.

Now then, after reading up on Reflection, this seems like the one to go with but no examples of a vb.net adding a new class.

any help would be great, any examples or links too or any other method to achieve this.

Thanks for any help


RE: Adding a new class dynamically on the fly ? - HFDone - Feb 2, 2019

dnlib https://github.com/0xd4d/dnlib/blob/master/Examples/Example2.cs


RE: Adding a new class dynamically on the fly ? - NYANxCAT - Feb 2, 2019

You can't modify an application using codedom.
Google "dnlib"


RE: Adding a new class dynamically on the fly ? - System[X] - Feb 2, 2019

(Feb 2, 2019 03:19 PM)HFDone Wrote:  dnlib https://github.com/0xd4d/dnlib/blob/master/Examples/Example2.cs

(Feb 2, 2019 03:20 PM)˗ˏˋ NYAN CAT ˎˊ˗ Wrote:  You can't modify an application using codedom.
Google "dnlib"


Thanks guys, but again this is c#. I tryed to convert but online converters have trouble with this.

Thanks


RE: Adding a new class dynamically on the fly ? - BahNahNah - Feb 2, 2019

(Feb 2, 2019 03:29 PM)System[X] Wrote:  Thanks guys, but again this is c#. I tryed to convert but online converters have trouble with this.

Thanks

Its a library. Add a refrence to the dll. No need to convert.


RE: Adding a new class dynamically on the fly ? - StarZ - Feb 2, 2019

Okay, You could also do this thru plugins. Just spit-balling here.


RE: Adding a new class dynamically on the fly ? - System[X] - Feb 3, 2019

(Feb 2, 2019 09:42 PM)BahNahNah Wrote:  Its a library. Add a refrence to the dll. No need to convert.

(Feb 2, 2019 10:46 PM)StarZ Wrote:  Okay, You could also do this thru plugins. Just spit-balling here.

I tryed that and it throws an error saying it can not find a manifest.

here is the class
Code
Imports Discord
Imports Discord.Commands
Imports Discord.WebSocket

Public Class TestCommands : Inherits ModuleBase(Of SocketCommandContext)

    <Command("test1")>
    <Remarks("User")>
    Public Async Function Test1() As Task
        Await ReplyAsync("this is test1")
    End Function

    <Command("test2")>
    <Remarks("User")>
    Public Async Function Test2() As Task
        Await ReplyAsync("this is test2")
    End Function

    <Command("test3")>
        <Remarks("User")>
        Public Async Function Test3() As Task
            Await ReplyAsync("this is test3")
        End Function

    End Class

All it is, is a discord bot but i would like to add a new commands class on the fly.

Thanks for any help


RE: Adding a new class dynamically on the fly ? - Sorzus - Feb 3, 2019

It is possible to generate assemblies in memory and load them in the current AppDomain, that can be done using https://github.com/dotnet/roslyn/wiki/Scripting-API-Samples (which is only for C#) or System.Reflection.Emit (which is only for IL). But you want to permanently add code to an existing assembly. Both cannot really achive that.

You actually have two problems here:
1. Compile the VB.Net to IL
2. Add the IL to an existing assembly

For the first, you just have to call a compiler. CodeDom is a wrapper around the .Net Framework Compiler, I would use that.

For the second problem, I have done things like that using Mono.Cecil which is very easy to use. You just have to load the dll or exe file that contains the code you want to add, and you can just copy types to the final assembly.

But note that these methods are very complicating and can fail in many ways (missing references, wrong references, etc.). Would you tell us why exactly you need to do that and not use a plugin framework? It sounds like that would be exactly what you need, and there are some very powerful available.


RE: Adding a new class dynamically on the fly ? - System[X] - Feb 3, 2019

(Feb 3, 2019 04:37 AM)Sorzus Wrote:  It is possible to generate assemblies in memory and load them in the current AppDomain, that can be done using https://github.com/dotnet/roslyn/wiki/Scripting-API-Samples (which is only for C#) or System.Reflection.Emit (which is only for IL). But you want to permanently add code to an existing assembly. Both cannot really achive that.

You actually have two problems here:
1. Compile the VB.Net to IL
2. Add the IL to an existing assembly

For the first, you just have to call a compiler. CodeDom is a wrapper around the .Net Framework Compiler, I would use that.

For the second problem, I have done things like that using Mono.Cecil which is very easy to use. You just have to load the dll or exe file that contains the code you want to add, and you can just copy types to the final assembly.

But note that these methods are very complicating and can fail in many ways (missing references, wrong references, etc.). Would you tell us why exactly you need to do that and not use a plugin framework? It sounds like that would be exactly what you need, and there are some very powerful available.

Reason for doing this is that if i give the discord bot to a friend to use on his server, he may want to add some new commands to it, the command class i posted above is the exact format.

Yes i could add a .txt file or something that has the command > replys but some commands are more than just string like to add roles ect.

I dont need to add it permantly to the exe just call the class on load, i could add a textbox to path of the class and a load button, to load the class befor you start the bot.

Thanks


RE: Adding a new class dynamically on the fly ? - Sorzus - Feb 3, 2019

(Feb 3, 2019 04:47 AM)System[X] Wrote:  Reason for doing this is that if i give the discord bot to a friend to use on his server, he may want to add some new commands to it, the command class i posted above is the exact format.

You are describing a simple plugin architecture here where you don't need any IL editing. Plugins are very easy to implement in .Net.

https://www.codeproject.com/Articles/1052356/Creating-a-Simple-Plugin-System-with-NET

Or if you'd need something more advanced, I would recommend a Dependency Injection framework, e. g. if you want to allow plugins to communicate with other plugins. MEF is another alternative which was especially made for plugins, but it is very complex and I don't think you need most it's features.

So, start with the first code project link, that is exactly what you need. Load an assembly into the AppDomain, find the right classes and load them.


RE: Adding a new class dynamically on the fly ? - System[X] - Feb 4, 2019

Im still unable to achieve this :/

The class has no method or type and nothing to invoke. The method that calls these function is in a module.

The class im wanting to load dynamically at runtime looks like this

Code
Imports Discord
Imports Discord.Commands
Imports Discord.WebSocket

Public Class TestCommands : Inherits ModuleBase(Of SocketCommandContext)

    <Command("test1")>
    <Remarks("User")>
    Public Async Function Test1() As Task
        Await ReplyAsync("this is test1")
    End Function

    <Command("test2")>
    <Remarks("User")>
    Public Async Function Test2() As Task
        Await ReplyAsync("this is test2")
    End Function

    <Command("test3")>
        <Remarks("User")>
        Public Async Function Test3() As Task
            Await ReplyAsync("this is test3")
        End Function

    End Class

Only 3 there but it could be 100+

I have tryed many different ways using Reflection, CodeDOM, making it a .dll file and also a txt file but still no luck. It would be great to just load a class.vb file at runtime as easy to edit than a dll

Thanks


RE: Adding a new class dynamically on the fly ? - Zettabit - Feb 7, 2019

You're forgetting to make an interface for all your plugins. Take a look again at the first link he posted. In your interface, make it return the available functions / commands that are available in that plugin, that way you can loop through and call the one you need.

I would post some code, but I'm on mobile so I can't right now. Just give it some more thought, and I'm sure you'll be able to figure it out.


RE: Adding a new class dynamically on the fly ? - 0xDEAD10CC - Feb 7, 2019

The link posted in this thread for plugin architecture is possibly one of the worst things you can do for a plugin framework. Nobody who knows what they're actually doing loads plugins in the main appdomain. I've made a decent plugin system before. Anybody with basic knowledge on how to use interfaces should be able to come up with at least a basic plugin system.


RE: Adding a new class dynamically on the fly ? - Sorzus - Feb 9, 2019

(Feb 7, 2019 11:45 PM)0xDEAD10CC Wrote:  The link posted in this thread for plugin architecture is possibly one of the worst things you can do for a plugin framework. Nobody who knows what they're actually doing loads plugins in the main appdomain. I've made a decent plugin system before. Anybody with basic knowledge on how to use interfaces should be able to come up with at least a basic plugin system.

He writes his own plugins, actually he knows exactly what they're doing (given he doesn't C&P the code from the internet ;) ). Loading them into a new app domain won't do a lot for protection, it's quite nice that you can unload them with this method but that's it. Multiple AppDomains are huge pain to handle.


RE: Adding a new class dynamically on the fly ? - 0xDEAD10CC - Feb 9, 2019

(Feb 9, 2019 03:26 AM)Sorzus Wrote:  He writes his own plugins, actually he knows exactly what they're doing (given he doesn't C&P the code from the internet ;) ). Loading them into a new app domain won't do a lot for protection, it's quite nice that you can unload them with this method but that's it. Multiple AppDomains are huge pain to handle.

Who said it was purely for protection? Although there are security properties, you can't "unload" a plugin if it's within the same appdomain really. The other difference is that if the plugin crashes, that exception if not caught will crash your entire program because it isn't isolated to a separate domain. They aren't really that much of a pain to deal with if you are by any means a decent developer that can design proper software.