Currently I'm compiling and loading an assembly at runtime. The assembly contains always the same namespaces and classes. When I'm doing this multiple times in the same application instance, does always the newest assembly will be used, when creating new instances of the classes which are in the assembly? Or is this not guaranteed?
2 Answers
You're creating exactly what you're trying to create. This may or may not be what you want to create, though.
Most likely, your assemblies don't have a specific name, but rather, a randomized unique name - in that case, the types are entirely different and only accidentally similar as far as .NET is concerned. Types from two different compilations are entirely unrelated, and are not compatible. This may or may not be a problem when you're accessing them through an interface defined outside of the dynamic assembly, depending on how exactly you're using the types.
If you add an assembly name, the situation gets a bit more complicated. You can't load the same assembly twice (the old one is not replaced by the new one), so you need to change the version. However, two versions of the same assembly cannot be loaded in the same application domain (except when doing "fun" with AssemblyResolve
etc. - but that's quite tricky to get right). The second assembly would simply fail to load.
In the end, the Type
you're trying to instantiate is the one you do instantiate (barring the use of binding redirects, which are bonus fun :P). If some piece of your code holds on to a Type
from a previous compilation, that's what it's going to create.

- 62,244
- 7
- 97
- 116
-
Thank you for your answer. So I should not get into trouble, because in this specific case I do not hold instances of types which are defined in an *old* assembly. Thanks a lot! Yep, they also have no name, cause I've already ran into trouble when giving them names :) – BendEg May 10 '16 at 07:16
-
1@BendEg Yup, that should work fine. Do note that the old assemblies aren't cleaned up, though, so if you're doing the compilation often in the same process, you might want to load them into a different AppDomain anyway (you can unload the domain when it's no longer useful). – Luaan May 10 '16 at 07:44
If your question is if I load an assembly in AppDomain
Assembly a1=Assembly.Load(Array of Assembly);
And then change code with roslyn like class name and create new assembly of your project and load it again
Assembly a2 =Assembly.Load(Array of Assembly);
Now is a2 is loaded in CurrentDomain ? My answer is no .a1 is now in CurrentDomain.
You can test it .
So for work with new assembly you have to use below solution.
You need to load this assembly in another AppDomain and every time you can Unload this AppDomain and create it again and load assembly again
First create a class that CurrentDomain will load instance of that to another AppDomain this object of class must load your assembly and it's dependencies to second AppDomain .
// you can create this class in another project and
// make assembly .because you need a copy of it in
//folder that you set for ApplicationBase of second AppDomain
public class AssemblyLoader : MarshallByRefObject
{
AssemblyLoader()
{
AppDomain.CurrentAppDomain.AssemblyResolve += LoaddependencyOfAssembly;
}
public void LoaddependencyOfAssembly(object sender,)
{
//load depdency of your assembly here
// if you has replaced those dependencies to folder that you set for ApplicationBase of second AppDomain doesn't need do anything here
}
public Assembly asm {get;set;}
public void LoadAssembly(MemoryStream ms)
{
asm= Assembly.Load(ms.ToArray());
}
}
in where you want to load assembly
AppDomainSetup s=new AppDomainSetup(){ApplicationBase="anotherFolderFromYourAppBinFoldr};
AppDomain ad= AppDomain.CreateDomain("name",AppDomain.CurrentDomain.Evidence,s);
Type t = typeof( AssemblyLoader);
AssemblyLoader al = ( AssemblyLoader) ad.CreateInstanceAndUnwrap(t.Assembly.FullName,t.FullName);
// load assembly here by Stream or fileName
al.LoadAssembly(ms );
// now assembly loaded on ad
// you can do your work with this assembly by al
// for example create a method in AssemblyLoader to
// get il of methods with name of them
// Below IL is in CurrentDomain
//when compiler goes to GetIlAsByteArray you are in second AppDomain
byte[] IL = al.GetILAsByteArray("NameOfMethod");
//And unload second AppDomain
AppDomain.Unload(ad);

- 1,763
- 3
- 17
- 55
-
Thanks for your answer. I've never worked with different AppDomains. Does this allow easy communication between the main AppDomain and the newly created? Thanks – BendEg May 10 '16 at 09:09
-
I have said in my answer.you can for example get il of methods in assembly and return it to first AppDomain.I will edit answer – mohsen May 10 '16 at 09:15
-
Thank you for that detailed answer and work. I'll try this and get back to you. +2 If i could... – BendEg May 10 '16 at 09:33
-
I had this problem so my code will work.may be bad typing is there.I was typing with mobile – mohsen May 10 '16 at 09:38
-
1Some more information about communication between AppDomains https://msdn.microsoft.com/en-us/library/system.marshalbyrefobject(v=vs.110).aspx – mohsen May 11 '16 at 09:16