Dynamically Generate Modules in same Assembly Space - c#

Consider I have a program running, which should do the following-
Should read some code from a text file and should execute it in its own Assembly space so that the new code being executed can access all components of the code already running.
How is that possible?? Help please.

By assembly space, do you mean AppDomain?
You might want to look at IronPython. As a scripting language it is better suited for being dynamically added to the program at runtime.
Otherwise:
You have access to the C# (and VB.NET) compiler via the Microsoft.CSharp.CSharpCodeProvider sitting in System.dll.
You can use it to compile that text file into a separate dll (possibly in-memory). Make sure that you add your currently executing assembly as a reference while compiling. Then you can either
load the assembly into the currently executing AppDomain. This way, it has access to all the objects in your application. You, however, cannot unload the code again. You'll have to unload the whole AppDomain (i.e. your application)
load the assembly into a separate AppDomain. You'll have to explicitly provide access to some of your objects via Remoting (or other in process communication methods), but you can unload/replace the code in case the text file changes.
Either way, you'll have to use reflection to call your dynamically loaded code.

Not sure how the magic works, but I'd look at MyGeneration, which is open source and acheives what you want to do. It can read a file of C#, VB.Net, and JScript and then build/compile those scripts and gives them access to it's own set of classes and assemblies.

Related

Using the same dll in another dll and a third codebase that runs the executable

So basically I am creating my own dll for use in a c# codebase, using c++ and a c-style layer for exporting functions. The issue is that both the c# part of the code (which actually runs and uses the dll) and my library itself both use another library (it's imgui, so lets call it such, even though it is irrelevant mostly) that runs on global state.
I initialize imgui to certain settings in my own dll and then use some of its functions in the c# code. Currently I am simply compiling the library into my dll and doing a c# binding myself that issues calls to imgui through my own dll. My question is whether I can use imgui as a dll for use both in my own dll and the main c# program in such a way that state is shared and the initialization step initializes the same code for both my own dll and the c# code.
That is, the c# code calls one of my functions in my own dll to initialize it, that function imports a dll (imgui), in the common directory for both my dll and the executable, and initializes IT. After this, the main c# program that imports both my dll and imgui then calls imgui functions to manipulate it's state. Will my dll and the main c# program be manipulating the same imgui state?
Generally yes
I say 'generally' because there are some conditions:
Everything needs to be in the same process (you are not clear on this but I assume so)
Both callers need to be able to get some handle on the state. So for example, if the state is memory allocated on the heap, then both callers need to be able to get a pointer to it, or else it needs to be a global variable somewhere they can access, either directly or indirectly.
Really it is the same as if it was 3 different C# modules
(also adding the disclaimer to think if you really need to use the C++, but I'm sure you have your reasons)

How to handle dll dependency that may not be present? [duplicate]

I am not sure the best way to explain this so please leave comments if you do not understand.
Basically, I have a few libraries for various tasks to work with different programs - notification is just one example.
Now, I am building a new program, and I want it to be as lightweight as possible. Whilst I would like to include my notification engine, I do not think many people would actually use its functionality, so, I would rather not include it by default - just as an optional download.
How would I program this?
With unmanaged Dlls and P/Invoke, I can basically wrap the whole lot in a try/catch loop, but I am not sure about the managed version.
So far, the best way I can think of is to check if the DLL file exists upon startup then set a field bool or similar, and every time I would like a notification to be fired, I could do an if/check the bool and fire...
I have seen from the debug window that DLL files are only loaded as they are needed. The program would obviously compile as all components will be visible to the project, but would it run on the end users machine without the DLL?
More importantly, is there a better way of doing this?
I would ideally like to have nothing about notifications in my application and somehow have it so that if the DLL file is downloaded, it adds this functionality externally. It really is not the end of the world to have a few extra bytes calling notification("blabla"); (or similar), but I am thinking a lot further down the line when I have much bigger intentions and just want to know best practices for this sort of thing.
I do not think many people would
actually use its functionality, so, I
would rather not include it by default
- just as an optional download.
Such things are typically described as plugins (or add-ons, or extensions).
Since .NET 4, the standard way to do that is with the Managed Exensibility Framework. It is included in the framework as the System.ComponentModel.Composition assembly and namespace. To get started, it is best to read the MSDN article and the MEF programming guide.
You can use System.Reflection.Assembly and its LoadFile method to dynamically load a DLL. You can then use the methods in Assembly to get Classes, types etc. embedded in the DLL and call them.
If you just check if the .dll exists or load every .dll in a plugin directory you can get what you want.
To your question if the program will run on the user's machine without the dlls already being present - yes , the program would run. As long as you dont do something that needs the runtime to load the classes defined in the dll , it does not matter if the dll is missing from the machine. To the aspect you are looking for regarding loading the dll on demand , I think you are well of using some sort of a configuration and Reflection ( either directly or by some IoC strategy. )
Try to load the plugin at startup.
Instead of checking a boolean all over the place, you can create a delegate field for the notification and initialize it to a no-op function. If loading the plugin succeeds, assign the delegate to the plugin implementation. Then everywhere the event occurs can just call the delegate, without worrying about the fact that the plugin might or might not be available.

Using AppDomain in C# to dynamically load and unload dll

In one of my application, which is related to system diagnostics, the related DLL is to be loaded and unloaded dynamically in C#. After some search I found that a separate DLL cannot be loaded dynamically its the complete AppDomain. So I have to create an AppDomain and use that DLL to be loaded unloaded dynamically. But I could not find anywhere how can I use that in code. I can not show the app code since it is against company rules.
Can somebody tell me some application code to use it. I want to load and unload the dll dynamically using appdomain and call a specific method in that dll, the dll does not have any entry point.
Thanks for answers.
Ashutosh
How to: Load Assemblies into an Application Domain
public static void Main()
{
// Use the file name to load the assembly into the current
// application domain.
Assembly a = Assembly.Load("example");
// Get the type to use.
Type myType = a.GetType("Example");
// Get the method to call.
MethodInfo myMethod = myType.GetMethod("MethodA");
// Create an instance.
object obj = Activator.CreateInstance(myType);
// Execute the method.
myMethod.Invoke(obj, null);
}
As for how to unload it, you have to unload the AppDomain itself, see this
AppDomain Temporary = AppDomain.CreateDomain("Temporary");
try
{
Gateway Proxy =
(Gateway) Temporary.CreateInstanceAndUnwrap("Shim", "Shim.Gateway");
Match M = Proxy.LoadAndMatch("Plugin.dll",
"Though the tough cough and hiccough, plough them through");
}
finally
{
AppDomain.Unload(Temporary);
}
It's difficult to understand your question, but I will try to make some suggestions.
There is no reason you cannot dynamically Load a dll directly into your application w/o a separate App Domain, the trick is that you cannot unload it. This is only important if you may load multiple versions of the same dll (i.e. you want the ability to update this diagnostic component to a new version without halting the execution of your application). If that is what you are trying to do, then I suggest this CodeProject article.
Actually you can dynamically load assemblies into your app domain and run code from it, the issue is that you cannot then unload the assembly. You can however load additional app domains (and assemblies into them) and unload the app domain when you are done.
As its name suggests though, you then have a new application domain, and you can't just simply call its code and use its types you need to marshal your calls and data across the domain boundaries. If you search you will find lots of examples on how to do this.
Something to consider though, is that this is a common pattern, and there are ready made solutions for it, the framework itself has a whole addin namespace that is dedicated to this type of plug-in behavior, it might be worth your while in having a close look at that first. There is an article here that shows how to use it.
Thanks guys, here is link where i found answer to my quetion:
The MSDN forum description for load and unload of assemblies dynamically
The other dll can be dynamically loaded and unloaded using another class which does load assembly and and call methods in that assembly...
AppDomain.CreateInstanceAndUnwrap generally wants input as assemblies from current project or generally current namespace. to solve that i need Assembly.LoadFrom(); to be used in some other class and create AppDomain and create instance of this class using AppDomain object as given in link.
Thanks for ur replies guys.

C# Controlling dll access

I have a program that utilises a plugin architecture. When the inital form loads, it scans the current directory, queries each dll and obtain some basic data which is displayed to the user.
Whilst using the program, the software will often need to ask the dll's to perform some work.
My question is, when the program initially checks the dll files, should I keep a reference to each dll object for future use, or should I query the dll files each time and create the object as and when needed?
if it's the first one, what is the best way to keep a list of an undetermined number of objects that derive from a common interface and then know which one to refer back to when needed?
Thanks.
Using the first one you could just create a
List<IYourCommonInterface> pluginDlls
and then just
pluginDlls.Add(dllReference);
Edit
Alternate method using a Dictionary, note that this will require you having some kind of ID for the dictionary that you can make use of to id the dlls.
Dictionary<SomeIDField, IYourCommonInterface> pluginDlls
pluginDlls.Add(dllRefrence);
Most apps do the check on load.
I wouldn't store the list of interfaces. If you do store them then you run into the possibility that the assemblies either disappear or are updated in some way. At which point you need to "refresh" them anyway.
Once you've loaded the assembly and gotten an instance of System.Reflection.Assembly for reflection (using Assembly.Load(), Assembly.LoadFrom(), Assembly.LoadFile(), etc.), the assembly is loaded. To quote MSDN on the subject:
...it is...possible to load specific assemblies into the current application domain
at runtime...There is no way to unload an individual assembly without unloading
all of the application domains that contain it. Even if the assembly goes out of
scope, the actual assembly file will remain loaded until all application domains
that contain it are unloaded. [emphasis mine]
So if you want to unload the DLLs until such time as you actually need them, you're going to have to create a new app domain and then unload that. Its easier to just load them and have done with it. You can keep the assemply reference around if you like, but if you call Assembly.Load() again, it won't actually load the assembly: it'll just get a reference to the previously loaded assembly.
If you've gone through the trouble of finding and loading the DLLs, normally you'll want to keep them around. This would depend mostly on how many resources the DLLs use and how your app is using the DLLs.
I'm assuming you're using LoadAssembly here. You can just store references to the assemblies you've loaded using some kind of map. Or even a list that you iterate through.
Perhaps if you give some more details we can help you better.

How Do I Load an Assembly and All of its Dependencies at Runtime in C# for Reflection?

I'm writing a utility for myself, partly as an exercise in learning C# Reflection and partly because I actually want the resulting tool for my own use.
What I'm after is basically pointing the application at an assembly and choosing a given class from which to select properties that should be included in an exported HTML form as fields. That form will be then used in my ASP.NET MVC app as the beginning of a View.
As I'm using Subsonic objects for the applications where I want to use, this should be reasonable and I figured that, by wanting to include things like differing output HTML depending on data type, Reflection was the way to get this done.
What I'm looking for, however, seems to be elusive. I'm trying to take the DLL/EXE that's chosen through the OpenFileDialog as the starting point and load it:
String FilePath = Path.GetDirectoryName(FileName);
System.Reflection.Assembly o = System.Reflection.Assembly.LoadFile(FileName);
That works fine, but because Subsonic-generated objects actually are full of object types that are defined in Subsonic.dll, etc., those dependent objects aren't loaded. Enter:
AssemblyName[] ReferencedAssemblies = o.GetReferencedAssemblies();
That, too, contains exactly what I would expect it to. However, what I'm trying to figure out is how to load those assemblies so that my digging into my objects will work properly. I understand that if those assemblies were in the GAC or in the directory of the running executable, I could just load them by their name, but that isn't likely to be the case for this use case and it's my primary use case.
So, what it boils down to is how do I load a given assembly and all of its arbitrary assemblies starting with a filename and resulting in a completely Reflection-browsable tree of types, properties, methods, etc.
I know that tools like Reflector do this, I just can't find the syntax for getting at it.
Couple of options here:
Attach to AppDomain.AssemblyResolve and do another LoadFile based on the requested assembly.
Spin up another AppDomain with the directory as its base and load the assemblies in that AppDomain.
I'd highly recommend pursuing option 2, since that will likely be cleaner and allow you to unload all those assemblies after. Also, consider loading assemblies in the reflection-only context if you only need to reflect over them (see Assembly.ReflectionOnlyLoad).
I worked out Kent Boogaart's second option.
Essentially I had to:
1.) Implement the ResolveEventHandler in a separate class, inheriting from MarshalByRefObject and adding the Serializable attribute.
2.) Add the current ApplicationBase, essentially where the event handler's dll is, to the AppDomain PrivateBinPath.
You can find the code on github.

Categories

Resources