In my previous post I showed how can you unload a assembly within an AppDomain and rebuild the assembly project without stoping the process that loaded the assembly.
In this post I'll show you how can you pass parameters to the newly created AppDomain. For this, you have to create a class that is decorated with Serializable attribute and create some properties that are the actual parameters (it is passed by value. If you want to pass by refrence, you must inherit from MarshalRefByObject - but you will stay in the main AppDomain).
[Serializable]
internal class CrossDomainObject
{
internal string Path { get; set; }
internal string Type { get ; set; }
internal object ObjectSent { get; set; }
internal void DomainCallBack()
{
//load assembly
Assembly assembly = Assembly.LoadFrom(Path);
AppDomain.CurrentDomain.Load(assembly.FullName);
//get type
Type type = assembly.GetType(Type);
if (type == null)
throw new NullReferenceException(
string.Format("Unable to get type: {0}", Type));
//create instance in remote domain
object instance= Activator.CreateInstance(type);
if (instance == null)
throw new NullReferenceException("Unable to create object in remote domain");
//get Controller property
PropertyInfo p = commandType.GetProperty("MyProperty");
if (p == null)
throw new NullReferenceException("Unable to get MyProperty property");
if (ObjectSent == null)
throw new NullReferenceException("Convert to ObjectSent failed!");
//Set value to the remote controller
p.SetValue(instance, ObjectSent , null);
}
}
The CrossAppDomainDelegate will invoke the DomainCallBack.
CrossDomainObject obj = new CrossDomainObject { ObjectSent = new List<object>(), Path = pathToAssembly, Type = typeOfInstance };
Today I wanted know how can I unload an assembly. After some Google/Bing/MSDN search, I realized that unloading an assembly is possible only and if only you create a new AppDomain, load the assembly in it and then Unload the AppDomain.
Some articles were about domain.CreateInstanceAndUnwrap(assemblyName, typeName) but the result was always the same: the assembly was loaded in the primary application domain. If you want to rebuild the assembly/project you will find out that it's not possible because the assembly was loaded in the main application domain and you will get and Error 2: file is being used by another process. But there's a trick.
In .NET Framework you can comunicate with others AppDomains using .NET Remoting. The comunication can be done using IPC Remoting (if you have a server and a client) or using the CrossAppDomainDelegate.
This blog entry will conver the case when you want to create a new AppDomain and create some objects in it without stoping the process that has the main application domain.
First of all, you will have to inherit your cross appdomain objects from MarshalByRefObject.
In the LoadAssembly method, you will have to create a new assembly, load the assembly in the newly created AppDomain, find the type of the object that you want to instantiate find methods/properties and call them.