Dynamically Compile Methods in a Class Library - c#

Say you have This, which is compiled into a dll:
namespace HelloWorld
{
public class Hello
{
public void WriteHello()
{
Console.Writeline("Hello World");
}
**public void WriteHello2()
{
Console.Writeline("Hello World2");
}**
}
}
I want the method WriteHello2 to actually be in a text file and compiled from there, in this program.
REASON
I want to create an interface where the user creates a method. Then I will write this method into a text file, and so whenever the program is run it will read in the text file, and execute that piece of code.
Example
Say my dll only consists of 1 method i.e. WriteHello.
The user runs the program, and then creates a new method say WriteHello2( he cannot create any method it is limited to my application). Now the dll should contain 2 methods.
I am not sure if any of this is possible.

To compile the code from a string, you can use the CompileAssemblyFromSource method. Things become more complicated if you want the changes to be persisted, that is, to have the program self-modify its binaries. I'm not sure if that's what you want, but it's doable with some clever temporary file juggling and process coordination.

Related

How do I add a working Main method to a dotnet 6 console application to access command line arguments?

I have a c# console application where I need to take some command line arguments.
For this reason I need a main method, instead of the non-main method that is currently there, and since I can't find any material on how to do it without.
So, I tried just pasting some code into my newly created visual studio dotnet 6 c# application:
static void Main(string[] args)
{
Console.WriteLine("hi there");
}
Which does'nt work. The code is not executed.
How do I add a main method, so I can take some cmd arguments?
You don't need a classic Main method to access command-line arguments. You can just access the "magic" variable args. The following is a complete and valid C# program (fiddle):
using System;
Console.WriteLine("I got " + args.Length + " command line arguments.");
This is documented here:
You don't declare an args variable. For the single source file that contains your top-level statements, the compiler recognizes args to mean the command-line arguments. The type of args is a string[], as in all C# programs.
For completeness: If you want a "classic" Main entry point, you need
a class or struct with
a static method called Main with
a return type of either void or int (or Task/Task<int>, if you create an async method) and
no parameter or a single string[] parameter.
It seems like you miss the class in your example. A full minimal working example looks like this:
using System;
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Hello World");
}
}
The exact criteria are documented here:
https://learn.microsoft.com/en-us/dotnet/csharp/fundamentals/program-structure/main-command-line
When you create the project, there is a box to check to not use top-level statements. Create a new project and check that box, then it will work just like in older versions. The box even has an info icon next to it that, when moused-over displays this message:
Whether to generate an explicit Program class and Main method instead of top-level statements.
If you do create a project with top-level statements, this URL is provided at the top of the code file. The information you needed was provided but you didn't pay attention. It's always important to pay attention to what VS is trying to tell you because it provides a lot of useful information.

C# : Calling a Method out of console application

I have a console app, that is used for importing stuff from a WS.
I'm really new to Console Apps so I have a question.
The Project contains a class called Importer.cs. This class has a Method called Initialize():
class Importer
{
static void Initialize()
{
//here i connect to the server etc.
}
}
Now I want to be able to call my APP like:
Importer.exe Initialize
So it should call the Initialize method, and then I would like to be able to go on with for example:
Importer.exe StartImport
I already work with the args[] parameter, but i'm quite stuck now.
Use a library like CommandLineParser and then use Reflection to call these method as MethodInfo objects.
In your console application, look in your solution explorer (in the right window of VS where all your files are shown). Find the one called PROGRAM.CS. Open it and look for this:
static void Main(string[] args)
{
}
Inside that, put this:
static void Main(string[] args)
{
//This starts a new instance of the Importer Class
Importer myImporter = new Importer();
//This calls the Initialize Method within Importer
Importer.Initialize();
//This calls the StartInput() Method within Importer
Importer.StartInput();
//Use Console.ReadLine() as the last line in this method to keep your screen open after program execution ends.
Console.ReadLine();
}
The first thing your console app runs ins Main() in console app.
Then, you simply test the project using F5. After testing, build the project and run by double-clicking the EXE file.
Depending on what you're exactly doing, this might not even work. I imagine a situation, where you Initialize() and afterwards StartImport(), but in between these 2 calls the program has been finished and the initialized state is gone. If you do not have methods like Initialize(), but rather atomic subcommands, your approach is possible in principle.
But there arises one question: Is this going to be generic? I mean: Say, you add another method. Do you then want to have the access to the method by a subcommand automatically established or wouldn't you mind adding another subcommand case? The first option would mean, you need to get comfortable with Reflection.
Now, say, you add methods, which you cannot declare private due to whatever reason, but you don't want them to be exposed as a subcommand. So you would need to keep track of the visibility. Sure, this would mean poor design, but if you're stuck with legacy components, this might just happen.
Now, let's say you need the Initialize() (or similar) command(s). They take care of a connection state or whatever and the program needs to still run, when the next subcommand is invoked, so it can use the initialized information, handles, etc.. Wouldn't it then make more sense to design your console application like a shell? So you would start with Importer.exe and get asked for subcommands.

How do I invoke .getmethodinfo?

I have recently started to read how a open source encryption program works.
The problem is, I'm stuck here on these 2 lines of code which I can't understand at all, I have looked at MSDN but it doesn't help me at all to understand what these 2 lines do.
MethodInfo run = Assembly.Load(InjRes).GetType("Resource.reflect").GetMethod("Run");
bool inj = (bool)run.Invoke(null, new object[] { Assembly.GetExecutingAssembly().Location, "", PayloadRes, false });
I'm also trying to figure out another way to accomplish the same thing, is there a way to invoke the .GetMethod?
This is fairly basic "reflection" in .NET.
Basically what happens here is:
Loads a .NET assembly as indicated by InjRes
Inside that assembly, get the type definition for Resource.reflect (which is probably a class)
Inside the Resource.reflect type, get the Run method and save it to variable run
Invoke (in other works, "execute") the Run() function on a null instance (which means Run() is probably a static method) with the parameters (Assembly.GetExecutingAssembly().Location, "", PayloadRes, false)
More simply, these lines would translate to "regular old C#" that looks like:
bool inj = Resource.reflect.Run(Assembly.GetExecutingAssembly().Location, "", PayloadRes, false);
but the original author probably couldn't have just written the simple 1 line above because either:
The assembly wasn't referenced at build-time, so the compiler doesn't know about the Resouce namespace so would have thrown a compile error
or the Resouce.reflect class or the Run method isn't public so couldn't have been called normally. Reflection can bypass this limitation.

Instantiating the class that contains static void Main()

I am reviewing a co-worker's C# console app, and I see this snippet:
class Program
{
static void Main(string[] args)
{
Program p = new Program();
p.RealMain();
}
... non-static RealMain function
}
Presumably, he's doing this because he wants to have instance-level fields, etc.
I haven't seen this before, but this style bugs me. Is it a common and accepted practice?
There is a school of thought that says that the main() function of object oriented code should do as little as possible. Main() is an "ugly" throwback to procedural code design, where programs were written in one function, calling subroutines only as necessary. In OOP, all code should be encapsulated in objects that do their jobs when told.
So, by doing this, you reduce the LOC in the main() entry point to two lines, and the real logic of the program is structured and executed in a more O-O fashion.
It makes sense to me.
In particular, you may want to add just enough logic into Main to parse the command line arguments - possibly using a generalized argument parser - and then pass those options into the constructor in a strongly-typed way suitable for the program in question.
Albin asked why this would be necessary. In a word: testability. In some cases it's entirely feasible to at least test some aspects of a top level program with unit tests or possibly integration tests. Using instance fields instead of static fields (etc) improves the testability here, as you don't need to worry about previous test runs messing up the state.
if you want to get non static functions you have to do like this.
class Program
{
static void Main(string[] args)
{
Program p = new Program(); // dependency of the class will be there.So not a good practice
p.RealMain();// if you want initalize, you have to go like this or better you can do it in some other class.
}
void RealMain(){}
}
Never seen it before. If you want to go with this pattern, create a separate Program2-class with RealMain and instantiate that instead.
Why do you need instance level fields? Is static fields not enough?
There could be a benefit if you internally want to instantiate many Program classes.
I don't see anything particularly wrong with this approach, I just don't have seen it before.
Application entry point is always defined as static void Main(...).
You can decide to write your code inside Main() or use this method to run something else located elsewhere... it's up to you decide...
The accepted practice is to create an instance of a separate class which can contain anything you need. The above snippet looks weird at least :).
If it was any other class but "Program" the question wouldn't have come up. This design gives you the opportunity to instantiate multiple instances of "Program", maybe threaded in the future, so why not. I'm with KeithS here: As few as possible in static void Main.
I see this a lot, particularly for quick console programs knocked up to try something out, or test something.
Visual Studio practically encourages it - if you ask for a new Console program, it generates a single file, with a class containing only a Main method.
Unless you are doing something complicated, which requires more than 1 class, or something very simple, which doesn't require a class at all (i.e. all methods and variables static)
why would you not do it this way?

What is the use of multiple main methods?

c# enables us to define more than one class with the method. Main method is the entry point for program execution. So why do we want to have more than one place for program execution. What is the advantage of multiple main methods over single main method.
Edit:
Example.cs
Class Example_1
{
public static void Main()
{
System.Console.WriteLine("Example 1")
}
public void test()
{
System.Console.WriteLine("Test method")
}
}
Class Example_2
{
public static void Main()
{
System.Console.WriteLine("Example 2")
}
}
If I type "csc Example.cs" then what would happen ?
What to do if I want to inherit test method of Class Example_1 in Class Example_2. Will this code work.
Example_1 abc = new Example_1();
abc.test();
You could use it so that different build configurations built the same executable but with different entry points - for example a console entry point vs a WinForms entry point.
Personally I use it when giving talks and in the sample code for C# in Depth. Each file is a self-contained example, but it's simpler to just have one entry point - so that entry point uses a utility class to prompt the user for which example they want to run.
First, if you have multiple main methods, you can specify which to use as the entry point for the application by your compiler.
Multiple main methods can be useful for testing purposes. Maybe you're developing a windows application like a text editor. If you are working on something like syntax highlighting, for example, you can have an extra main method which starts the GUI, loads a test file and enables the appropriate syntax highlighting.
Another example can be an application which will be compiled for console use only or as an windows application involving two different classes with main methods.
There can only be one entry point in a C# program. If you have more than one class that has a Main method, you must compile your program with the /main compiler option to specify which Main method to use as the entry point.
Compile t2.cs and t3.cs, specifying that the Main method will be found in Test2 like this,
csc t2.cs t3.cs /main:Test2
You can have multiple methods called Main() in different classes. But only one of them is used to start the program. It is just normal method, you can use the other Main's for whatever you wish. (But it is not recommended.)
It would probably be a rare occurrence, but I'd imagine if you had to link to some external code that has a Main() method, then you'd want to tell the compiler to use yours.
Why shouldn't you be able to create multiple classes with a Main method? After all, Main is just the name of the method. If you create a class it's perfectly ok to define a method named Main in it.
When you Using Visual Studio CMD Prompt
then Try to execute as given below:
csc filename.cs /main:classname
where filename is the name of the file where the code is stored and classname is the name of the class containing the Main which we would like to be the entry point.
As in given program there are two class A and B in which each containing A Main Method. We may write as
csc filename.cs /main:A [ for Class A Main Execution ] or,
csc filename.cs /main:B [ for Class B Main Execution ]

Categories

Resources