Ok so... I have a WPF application (let's call it Launcher.exe) which loads and executes another WPF application (let's call it Loaded.exe) dynamically using something like this:
Byte[] assemblyData;
using (BinaryReader reader = new BinaryReader(new FileStream(filePath, FileMode.Open)))
assemblyData = reader.ReadBytes(Convert.ToInt32(fs.Length));
Assembly assembly = Assembly.Load(assemblyData);
MethodInfo method = assembly.EntryPoint;
if (method != null)
{
Object instance = assembly.CreateInstance(method.Name);
method.Invoke(o, null);
}
Now... the problem is that Launched.exe has its own settings in the file Loaded.exe.config, and it also uses them in bindings. For example:
Topmost="{Binding Mode=TwoWay, Path=Topmost, Source={x:Static p:Settings.Default}}"
First question is, how can I make my dynamically loaded assembly properly load/bind/update and, more generally, use its own settings? I don't think it can handle this automagically...
Second question is: can Loaded.exe communicate with Launcher.exe? Let's say Loaded.exe needs some data that only Launcher.exe can retrieve... how can it ask for it? I think I need something like a proxy between the two assemblies, but I can't even figure out how to start coding this...
I supose you'll need to load a separate assembly with it's own .config file, no?
One way i do that is to load the assembly in a new AppDomain. You'll could deploy that assembly in a separate folder with all his needed references.
First setup the AppDomain, here you have a method:
AppDomain getAppDomainForAssembly(string assemblypath, string appdomainname)
{
//this._assembly_file = AssemblyFile;
string _assembly_file_name = System.IO.Path.GetFileName(assemblypath);
string _rootpath = System.IO.Path.GetDirectoryName(assemblypath);
//this._assembly_class_name = AssemblyClassNameToInstance;
AppDomainSetup _app_domain_info = new AppDomainSetup();
_app_domain_info.ApplicationBase = _rootpath;
_app_domain_info.PrivateBinPath = _rootpath;
_app_domain_info.PrivateBinPathProbe = _rootpath;
_app_domain_info.ConfigurationFile = _rootpath + #"\app.config"; //Here put the path to the correct .assembly .config file
AppDomain _app_domain = AppDomain.CreateDomain(
appdomainname, null, _app_domain_info);
return _app_domain;
}
Then get an instance of the object that executes the method on the assembly:
protected System.Reflection.Assembly _asm_resolve(string assemblyFile)
{
return System.Reflection.Assembly.LoadFrom(assemblyFile);
}
object getInstanceFromAppDomain(ref AppDomain appDomain,
string assemblyPath, string className = null)
{
if (string.IsNullOrEmpty(className))
{
System.Reflection.Assembly assembly = _asm_resolve(assemblyPath);
System.Reflection.MethodInfo method = assembly.EntryPoint;
return appDomain.CreateInstanceFromAndUnwrap(assemblyPath, method.Name);
}
else
{
return appDomain.CreateInstanceFromAndUnwrap(assemblyPath, className);
}
}
Even if we know the Object Type, we could create a method with generic type:
T getInstanceFromAppDomain<T>(ref AppDomain appDomain,
string assemblyPath, string className = null)
{
if (string.IsNullOrEmpty(className))
{
System.Reflection.Assembly assembly = _asm_resolve(assemblyPath);
System.Reflection.MethodInfo method = assembly.EntryPoint;
return (T)appDomain.CreateInstanceFromAndUnwrap(assemblyPath, method.Name);
}
else
{
return (T)appDomain.CreateInstanceFromAndUnwrap(assemblyPath, className);
}
}
And then, invoke the method on the created instance, wich is executing in the new appDomain:
void executeMethod(Type objecttype, string methodname, ref object instancedObject, object[] methodparams)
{
objecttype.InvokeMember(
methodname, System.Reflection.BindingFlags.InvokeMethod, null, instancedObject, methodparams);
}
You could use like this:
AppDomain newappdomain = getAppDomainForAssembly(filePath, "Loaded.exe.domain");
object loadedexe_object = getInstanceFromAppDomain(ref newappdomain,
filePath);
//If you know the method name to call...
executeMethod(loadedexe_object.GetType(), "methodname", ref loadedexe_object, null);
//or get entry point...
executeMethod(loadedexe_object.GetType(),
_asm_resolve(filePath).EntryPoint.Name, ref loadedexe_object, null);
For the second question, you could use NamedPipes, Remoting, WCF...
You need to implement interprocess communication on the same machine.
Take a look at MSDN documentaion, code sample covering this scenario with WCF
http://msdn.microsoft.com/en-us/library/system.servicemodel.netnamedpipebinding.aspx
See this sample on CodeProject, using Remoting
Inter-process communication via Remoting
Related
I'm trying to load a DLL file into a separated app domain and invoke a method in the DLL file and get some response from it. The DLL file did not exist in the project bin folder when the application starts, the DLL file is loaded from another folder. After I have done with the DLL file I want to unload the app domain that I have just created.
The steps:
Created a new app domain
Load my DLL I want to the app domain
Invoke the method and get response
Unload the app domain
Here is what I've tried so far
This is the code in MyAssembly.dll
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
namespace MyAssembly
{
public class MyClass
{
public static string MyMethod()
{
return "Hello there, this is message from MyAssembly";
}
}
}
Here is how I load the DLL file
using System.Diagnostic;
using System.IO;
private class ProxyClass : MarshalByRefObject
{
public void LoadAssembly()
{
AppDomain dom;
string domainName = "new:" + Guid.NewGuid();
try
{
//Create the app domain
dom = AppDomain.CreateDomain(domainName, null, new AppDomainSetup
{
PrivateBinPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "bin"),
ApplicationBase = AppDomain.CurrentDomain.BaseDirectory,
ConfigurationFile = AppDomain.CurrentDomain.SetupInformation.ConfigurationFile,
ApplicationName = AppDomain.CurrentDomain.SetupInformation.ApplicationName,
ShadowCopyFiles = "true",
ShadowCopyDirectories = "true",
LoaderOptimization = LoaderOptimization.SingleDomain,
});
string dllPath = #"C:\MyProject\MyAssembly.dll";//the path to my assembly file I want to load
//load the assembly to the new app domain
Assembly asm = dom.Load(File.ReadAllBytes(dllPath));//Error occurred at here
Type baseClass = asm.GetType("MyAssembly.MyClass");
MethodInfo targetMethod = baseClass.GetMethod("MyMethod");
string result = targetMethod.Invoke(null, new object[]{});
/*Do something to the result*/
}
catch(Exception ex)
{
Debug.WriteLine(ex.Message);
Debug.WriteLine(ex.ToString());
}
finally
{
//Finally unload the app domain
if (dom != null) AppDomain.Unload(dom);
}
}
}
public void BeginLoadDll()
{
ProxyClass proxy = new ProxyClass();
proxy.LoadAssembly();
//OR like this, which gave me same error message as well
//var dom = AppDomain.CreateDomain("new:" + Guid.NewGuid(), null, new AppDomainSetup
// {
// PrivateBinPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "bin"),
// ApplicationBase = AppDomain.CurrentDomain.BaseDirectory,
// ConfigurationFile = AppDomain.CurrentDomain.SetupInformation.ConfigurationFile,
// ApplicationName = AppDomain.CurrentDomain.SetupInformation.ApplicationName,
// ShadowCopyFiles = "true",
// ShadowCopyDirectories = "true",
// LoaderOptimization = LoaderOptimization.SingleDomain,
// });
//ProxyClass proxy = (ProxyClass)dom.CreateInstanceAndUnwrap(
// typeof(ProxyClass).Assembly.FullName, typeof(ProxyClass).FullName);
//pr.LoadAssembly(watcherData, filePath);
}
Here is something I've observed so far, I'm not sure if that is just me or I'm missing something
-If the "MyAssembly.dll" exists in the project bin folder before the application starts, I can load the dll file
-If the "MyAssembly.dll" did not exist in the project bin folder before application starts, instead it was loaded somewhere else other than the project bin folder, I cannot load the dll file. For example, the project bin folder is "C:\Main\MyMainProject\MyMainProject\bin", and DLL is loaded from C:\MyProject\MyAssembly.dll"
-If I move the "MyAssembly.dll" file into the bin folder (using File.Copy() or File.Move()), it somehow stop the rest of the code to be executed.
The error message I received
Could not load file or assembly 'MyAssembly, Version=1.0.0.0,
Culture=neutral, PublicKeyToken=2c20c56a5e1f4bd4' or one of its dependencies.
The system cannot find the file specified.
EDIT
I know I can use Assembly.LoadFrom(#"PATH\TO\MY\DLL"), but the problem with this one is I cannot unload the DLL
After days of research, I finally got it working. Below is my final working code.
Useful reference links that helped me achieved this
https://learn.microsoft.com/en-us/dotnet/api/system.appdomain.createinstanceandunwrap?view=netframework-4.8#System_AppDomain_CreateInstanceAndUnwrap_System_String_System_String_
C# reflection - load assembly and invoke a method if it exists
Using AppDomain in C# to dynamically load and unload dll
The code in MyAssembly.dll is same as in the question. I also realized that I can return an object type as well.
How I load the DLL file into separated app domain and unload the app domain
public void MethodThatLoadDll()
{
AppDomain dom = null;
//declare this outside the try-catch block, so we can unload it in finally block
try
{
string domName = "new:" + Guid.NewGuid();
//assume that the domName is "new:50536e71-51ad-4bad-9bf8-67c54382bb46"
//create the new domain here instead of in the proxy class
dom = AppDomain.CreateDomain(, null, new AppDomainSetup
{
PrivateBinPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "bin"),
ApplicationBase = AppDomain.CurrentDomain.BaseDirectory,
ConfigurationFile = AppDomain.CurrentDomain.SetupInformation.ConfigurationFile,
ApplicationName = AppDomain.CurrentDomain.SetupInformation.ApplicationName,
ShadowCopyFiles = "true",
ShadowCopyDirectories = "true",/*yes they are string value*/
LoaderOptimization = LoaderOptimization.SingleDomain,
DisallowBindingRedirects = false,
DisallowCodeDownload = true,
});
ProxyClass proxy = (ProxyClass)dom.CreateInstanceAndUnwrap(
typeof(ProxyClass).Assembly.FullName, typeof(ProxyClass).FullName);
string result = proxy.ExecuteAssembly("MyParam");
/*Do whatever to the result*/
}
catch(Exception ex)
{
//handle the error here
}
finally
{
//finally unload the app domain
if(dom != null) AppDomain.Unload(dom);
}
}
My class that inherits MarshalByRefObject
private class ProxyClass : MarshalByRefObject
{
//you may specified any parameter you want, if you get `xxx is not marked as serializable` error, see explanation below
public string ExecuteAssembly(string param1)
{
/*
* All the code executed here is under the new app domain that we just created above
* We also have different session state here, so if you want data from main domain's session, you should pass it as a parameter
*/
//load your DLL file here
Debug.WriteLine(AppDomain.CurrentDomain.FriendlyName);
//will print "new:50536e71-51ad-4bad-9bf8-67c54382bb46" which is the name that we just gave to the new created app domain
Assembly asm = Assembly.LoadFrom(#"PATH/TO/THE/DLL");
Type baseClass = asm.GetType("MyAssembly.MyClass");
MethodInfo targetMethod = baseClass.GetMethod("MyMethod");
string result = targetMethod.Invoke(null, new object[]{});
return result;
}
}
A common error that you may run into
'xxx' is not marked as serializable
This could happen if you try to pass a custom class as parameter, like this
public void ExecuteAssembly(MyClass param1)
In this case, put a [Serializable] to MyClass, like this
[Serializable]
public class MyClass { }
I searched a lot about reloading an assembly at runtime in .NET. The only method I can find is using another AppDomain. But this makes things really complicated. And it is almost impossible in my case because the classes in the assembly which is going to be loaded at runtime do not inherit from MarshalByRefObject. I've looked at Unity game engine. The editor builds the components at runtime and just uses the compiled assembly. How is it possible?
I have done this using MEF. I am not sure if it is an option for you, but it works well. However even with MEF it is somewhat complicated.
On my case I am loading all the dll from a particular folder.
These are the setup classes.
public static class SandBox
{
public static AppDomain CreateSandboxDomain(string name, string path, SecurityZone zone)
{
string fullDirectory = Path.GetFullPath(path);
string cachePath = Path.Combine(fullDirectory, "ShadowCopyCache");
string pluginPath = Path.Combine(fullDirectory, "Plugins");
if (!Directory.Exists(cachePath))
Directory.CreateDirectory(cachePath);
if (!Directory.Exists(pluginPath))
Directory.CreateDirectory(pluginPath);
AppDomainSetup setup = new AppDomainSetup
{
ApplicationBase = fullDirectory,
CachePath = cachePath,
ShadowCopyDirectories = pluginPath,
ShadowCopyFiles = "true"
};
Evidence evidence = new Evidence();
evidence.AddHostEvidence(new Zone(zone));
PermissionSet permissions = SecurityManager.GetStandardSandbox(evidence);
return AppDomain.CreateDomain(name, evidence, setup, permissions);
}
}
public class Runner : MarshalByRefObject
{
private CompositionContainer _container;
private DirectoryCatalog _directoryCatalog;
private readonly AggregateCatalog _catalog = new AggregateCatalog();
public bool CanExport<T>()
{
T result = _container.GetExportedValueOrDefault<T>();
return result != null;
}
public void Recompose()
{
_directoryCatalog.Refresh();
_container.ComposeParts(_directoryCatalog.Parts);
}
public void RunAction(Action codeToExecute)
{
MefBase.Container = _container;
codeToExecute.Invoke();
}
public void CreateMefContainer()
{
RegistrationBuilder regBuilder = new RegistrationBuilder();
string pluginPath = AppDomain.CurrentDomain.SetupInformation.ApplicationBase;
_directoryCatalog = new DirectoryCatalog(pluginPath, regBuilder);
_catalog.Catalogs.Add(_directoryCatalog);
_container = new CompositionContainer(_catalog, true);
_container.ComposeExportedValue(_container);
Console.WriteLine("exports in AppDomain {0}", AppDomain.CurrentDomain.FriendlyName);
}
}
Here is the actual code.
AppDomain domain = SandBox.CreateSandboxDomain($"Sandbox Domain_{currentCount}", directoryName, SecurityZone.MyComputer);
foreach (FileInfo dll in currentDlls)
{
string path = Path.GetFullPath(Path.Combine(directoryName, dll.Name));
if (!File.Exists(path))
File.Copy(dll.FullName, Path.Combine(directoryName, dll.Name), true);
domain.Load(typeof(Runner).Assembly.FullName);
}
You can get the domain back by doing this.
Runner runner = (Runner) domain.CreateInstanceAndUnwrap(typeof(Runner).Assembly.FullName, typeof(Runner).FullName);
runner.CreateMefContainer(); // or runner.Recompose();
You will need to call your code like this.
runner.RunAction(() =>
{
IRepository export = MefBase.Resolve<IRepository>();
export?.Get("123");
Console.WriteLine("Executing {0}", export);
});
Generally speaking, you cannot reload assembly within the same AppDomain. You can create one dynamically and load it (and it will sit in your AppDomain forever), you can load another almost-but-not-quite-the-same copy of your assembly, but once the assembly is in AppDomain, it's stuck.
Imagine that a library assembly defines SomeType and your client code just created an instance. If you unload the library, what is supposed to happen with this instance? If the library is in another AppDomain, the client will use a proxy with a well-defined (in MarshalByRefObject) behaviour (to go zomby with the domain unload and throw exceptions foreverafter). Supporting unloading of arbitrary types would have made the runtime incredibly complicated, unpredictable or both.
As for Unity, see this discussion. Quote:
An "assembly reaload" sounds like some kind of quick update check but in fact the whole scripting environment reloads. This will destroy everything in the managed land. Unity can recover from this by using it's serialization system. Unity serializes the whole scene before the reload, then recreates everything and deserializing the whold scene. Of course only things which can be serialized will "survive" this process.
I hope it wouldn't be a duplicate, I see plenty of similar questions, but any of them help can't help me.
I have such Method code in nameofdll.dll:
DllMethod()
{
Assembly assembly = Assembly.GetExecutingAssembly();
Type type = assembly.GetType("Class");
MethodInfo method = type.GetMethod("Method");
object obj = Activator.CreateInstance(type);
method.Invoke(...);
}
and Class - constructor add AssemblyResolver
class Class
{
public Class()
{
AppDomain.CurrentDomain.AssemblyResolve += new ResolveEventHandler(MyResolveEventHandler);
}
public void Method()
{...}
private Assembly MyResolveEventHandler(object sender, ResolveEventArgs args)
{...}
}
Till now AssemblyResolver is invoked when I call metod from my main app.exe which is in the same folder as nameofdll.dll, let's name the folder as mainfolder and also from powershell script in this way:
load dll(mainfolder + nameofdll.dll)
call DllMethod()
Everything works fine, but I have to unload dll which AssemblyResolver had loaded, because Method is called multiple times witch different dlls versions.
So I modified DllMethod() like that:
{
Assembly assembly = Assembly.GetExecutingAssembly();
MethodInfo method = type.GetMethod("Method");
//new part
AppDomainSetup domainSetup = new AppDomainSetup();
domainSetup.ApplicationBase = Path.GetDirectoryName(assembly.Location);
AppDomain Domain = AppDomain.CreateDomain(Class, null, domainSetup);
object obj = Domain.CreateInstanceAndUnwrap(assembly.FullName, Class);
method.Invoke(...);
AppDomain.Unload(Domain);
}
I use
domainSetup.ApplicationBase = Path.GetDirectoryName(assembly.Location);
because BaseDirecotry was powershell folder and CreateInstanceAndUnwrap fails to find nameofdll.dll.
And finally the problem is that everyting is ok when using app.exe, but when I called that dll method from powershell script, the AssemblyResolver wasn't invoked and immediately I got error that it could not load some dlls.
I also try to copy domain setting, and add
AppDomainSetup domainSetup = AppDomain.CurrentDomain.SetupInformation;
where CurrentDomain is domain in which AssemblyResolver works fine before, but it didn't solve the problem.
I am trying to create a Windows sandbox application, building upon the "How to" found here: "https://msdn.microsoft.com/en-us/library/bb763046(v=vs.110).aspx"
In the example it loads a specific type from a DLL whereas I would like to be able to execute an assembly from its entry point with restricted permissions.
The program I am using for testing purposes is a simple hello world application.
using System;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Hello World!");
Console.Read();
}
}
}
I have tried two different methods to try and achieve this.
Method 1.
Use the "MethodInfo.Invoke" method on the entry point of the assembly.
MethodInfo target = Assembly.Load(assemblyName).EntryPoint;
target.Invoke(null, parameters);
This produces a Method Access Exception due to the main method being non-public. A simple way around this would be to make the main method public but I will not have this sort of access to the assemblies that are intended to be used with this application.
Method 2.
Use the "AppDomain.ExecuteAssembly" method as shown below.
newDomain.ExecuteAssembly(filePath, parameters);
This requires that the app domain has both File IO Permission and UI Permission for the assembly to be executed but I want to be able to restrict the assembly from having these permissions.
Is there a way to execute an assembly from it's entry point within a permission restricted app domain?
EDIT: The assembly's location is provided from an Open File Dialog and is then passed to the following method.
public int RunAssembly(string filePath, string[] parameters)
{
AppDomainSetup adSetup = new AppDomainSetup();
adSetup.ApplicationBase = Path.GetDirectoryName(filePath);
PermissionSet permSet = new PermissionSet(PermissionState.None);
permSet.AddPermission(new SecurityPermission(SecurityPermissionFlag.Execution));
StrongName fullTrustAssembly = typeof(Sandboxer).Assembly.Evidence.GetHostEvidence<StrongName>();
newDomain = AppDomain.CreateDomain("Sandbox", null, adSetup, permSet, fullTrustAssembly);
return newDomain.ExecuteAssembly(filePath, parameters);
}
As you can see the only permission I would like to give the new app domain is the ability to run. Whereas it required File IO and UI permissions for the ExecuteAssembly method to work correctly.
You wrote: "This produces a Method Access Exception due to the main method being non-public." Yes, you shouldn't call a method which is not intended to be called from outside. You try to "override" the protection level: I hope it's not possible as it means a big hole in the system.
Using Method #1 and adding the reflection permission RestrictedMemberAccess so that non-public members can be invoked is a way of invoking an assembly with fully restricted permissions.
MethodInfo target = Assembly.Load(assemblyName).EntryPoint;
(new ReflectionPermission(ReflectionPermissionFlag.RestrictedMemberAccess)).Assert();
target.Invoke(null, parameters);
The full loading code:
public int RunAssembly(string filePath, Object[] parameters)
{
AppDomainSetup adSetup = new AppDomainSetup();
adSetup.ApplicationBase = Path.GetDirectoryName(filePath);
PermissionSet permSet = new PermissionSet(PermissionState.None);
permSet.AddPermission(new SecurityPermission(SecurityPermissionFlag.Execution));
StrongName fullTrustAssembly = typeof(Sandboxer).Assembly.Evidence.GetHostEvidence<StrongName>();
newDomain = AppDomain.CreateDomain("Sandbox", null, adSetup, permSet, fullTrustAssembly);
ObjectHandle handle = Activator.CreateInstanceFrom(
_newDomain, typeof(Sandboxer).Assembly.ManifestModule.FullyQualifiedName,
typeof(Sandboxer).FullName
);
newDomainInstance = (Sandboxer)handle.Unwrap();
string assemblyName = Path.GetFileNameWithoutExtension(filePath);
return newDomainInstance.ExecuteAssembly(assemblyName, parameters);
}
public int ExecuteAssembly(string assemblyName, Object[] parameters)
{
MethodInfo target = Assembly.Load(assemblyName).EntryPoint;
(new ReflectionPermission(ReflectionPermissionFlag.RestrictedMemberAccess)).Assert();
return target.Invoke(null, parameters);
}
Sorry for the ambiguous method name, these should be changed if it to be used.
I know it has been a while but I came to this question and here what I ended up with.
first, import system.security
using System.Security;
using System.Security.Permissions;
And here is the execution using DomainApp.
public static void ExecuteAssemblyLoadFileAppDomain(string file, string[] param)
{
Console.WriteLine("[*] Using ExecuteAssemblyLoadFileAppDomain1:");
PermissionSet permission = new PermissionSet(PermissionState.Unrestricted);
AppDomainSetup setup = new AppDomainSetup();
setup.ApplicationBase = AppDomain.CurrentDomain.SetupInformation.ApplicationBase;
AppDomain domain = AppDomain.CreateDomain("King AppDomain", null, setup, permission);
try
{
Console.WriteLine($"[+] Executing '{Path.GetFileName(file)}' in '{domain.FriendlyName}' AppDomain.");
domain.ExecuteAssembly(file, param);
}
catch (Exception e)
{
Console.WriteLine(e);
}
finally
{
AppDomain.Unload(domain);
}
}
I have a assembly. In this assembly I have a class and interface. I need to load this assembly at runtime and want to create an object of the class and also want to use the interface.
Assembly MyDALL = Assembly.Load("DALL"); // DALL is name of my dll
Type MyLoadClass = MyDALL.GetType("DALL.LoadClass"); // LoadClass is my class
object obj = Activator.CreateInstance(MyLoadClass);
This is my code. How could it be improved?
If your assembly is in GAC or bin use the assembly name at the end of type name instead of Assembly.Load().
object obj = Activator.CreateInstance(Type.GetType("DALL.LoadClass, DALL", true));
You should Use Dynamic Method with for Improving. its faster than reflection..
Here is a sample code for creating Object using Dynamic Method..
public class ObjectCreateMethod
{
delegate object MethodInvoker();
MethodInvoker methodHandler = null;
public ObjectCreateMethod(Type type)
{
CreateMethod(type.GetConstructor(Type.EmptyTypes));
}
public ObjectCreateMethod(ConstructorInfo target)
{
CreateMethod(target);
}
void CreateMethod(ConstructorInfo target)
{
DynamicMethod dynamic = new DynamicMethod(string.Empty,
typeof(object),
new Type[0],
target.DeclaringType);
ILGenerator il = dynamic.GetILGenerator();
il.DeclareLocal(target.DeclaringType);
il.Emit(OpCodes.Newobj, target);
il.Emit(OpCodes.Stloc_0);
il.Emit(OpCodes.Ldloc_0);
il.Emit(OpCodes.Ret);
methodHandler = (MethodInvoker)dynamic.CreateDelegate(typeof(MethodInvoker));
}
public object CreateInstance()
{
return methodHandler();
}
}
//Use Above class for Object Creation.
ObjectCreateMethod inv = new ObjectCreateMethod(type); //Specify Type
Object obj= inv.CreateInstance();
This method takes only 1/10th time needed by Activator.
Check out http://www.ozcandegirmenci.com/post/2008/02/Create-object-instances-Faster-than-Reflection.aspx
Check out http://www.youtube.com/watch?v=x-KK7bmo1AM
To modify his code to load multiple assemblies use
static Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args)
{
string assemblyName = args.Name.Split(',').First();
using (var stream = Assembly.GetExecutingAssembly().GetManifestResourceStream("YourNamespace." + assemblyName + ".dll"))
{
byte[] assemblyData = new byte[stream.Length];
stream.Read(assemblyData, 0, assemblyData.Length);
return Assembly.Load(assemblyData);
}
}
In your main method put
AppDomain.CurrentDomain.AssemblyResolve += CurrentDomain_AssemblyResolve;
Be sure to add your assemblies to your project and change the build action property to "Embedded Resource".