Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
HomeAnnouncementsFree MagazinesWhite PapersSubmit Content
Discussion GroupsASP.NETWindows FormsLanguages.NET FrameworkVisual Studio.NET
Articles.NET FrameworkASP.NETToolsWindows Forms
.NET DirectoryOpen Source ProjectsUser GroupsWeb Resources
Related Topics
Visual Basic 6SQL ServerMS AccessOther DB ProductsMS Server ProductsMore Topics ...

.NET Forum / Languages / C# / January 2008

Tip: Looking for answers? Try searching our database.

Loading assemblies in another domain gets the assembly loaded in the default domain too!?!?!?

Thread view: 
Enable EMail Alerts  Start New Thread
Thread rating: 
Jeff - 11 Jan 2008 08:22 GMT
Hi

I'm trying to achieve a scenario where I have c# files that are compiled
dynamically, the assemblies are then loaded in a different AppDomain, I call
a simple method from the object, and then unload the AppDomain to release
the lock on the assemly files (so to I can compile the code again if it has
been modified). However, I've encountered a problem, whereby the assembly is
also loaded in the default AppDomain!

I have a few classes (see below):
1) ScriptManager - basically keeps a list of scripts and loads and return
plugins to main program where methods are called on the assemblies
2) PlugIn              - Loaded assembly
3) CodeCompiler - Compiles the code files into dlls

My problem lies in the ScriptManager class on the call to GetScript() with
the piece of code :
plug = new PlugIn(sDLLPath, ScriptDomain);
At this point, the assembly (which was loaded in the other domain), gets
loaded in the default AppDomain too! I have checked in the PlugIn class,
it's fine there but only when the object is returned to ScriptManager that
this happens.

Can anyone please tell me if i'm doing something wrong? Or how to resolve
the issue?

Thanks
Jeff

Code :
==========================  Call from main program
===============================
ScriptManager m_ScriptMgr;

PlugIn ScriptTimeAdjuster;

for (int i = 0; i < 5; i++)

{

m_ScriptMgr = new ScriptManager();

ScriptTimeAdjuster = m_ScriptMgr.GetScript("TR_TimeAdjuster");

if (ScriptTimeAdjuster != null)

{

ScriptTimeAdjuster.UnloadPlugin();

}

ScriptTimeAdjuster = null;

m_ScriptMgr.ClearAllScripts();

}

===========================  PlugIn class
=======================================
public class PlugIn
{

   private Type _type;

   private Object _obj;

   private ObjectHandle _objHandle;

   private AppDomain _domain;

   public readonly string Name;

public PlugIn(string file, AppDomain domain)

{

   Name = file;

   _domain = domain;

   LoadPlugin(file);

}

public bool LoadPlugin(string file)

{

   bool retour = false;

   try

   {

       Assembly a.s = _domain.Load("TR_TimeAdjuster",_domain.Evidence);

       _type = a.s.GetType("Scripts.TR_TimeAdjuster");

       _obj = a.s.CreateInstance(_type.FullName);

       retour = true;

   }

   catch (Exception ex)

   {retour = false;}

   return (retour);

}

/// <summary>

/// Execute a method in the plugin

/// </summary>

public object ExecuteMethod(string MethodName, Nullable<BindingFlags> Flags,
Binder Binder, object[] MethodParameters)

{

   BindingFlags InvokeFlags = BindingFlags.InvokeMethod;

   Binder InvokeBinder = Binder;

   try

   {

       if (_type == null || _obj == null) return null;

       if (Flags != null) InvokeFlags = (BindingFlags) Flags;

       return _type.InvokeMember(MethodName, InvokeFlags, Binder, _obj,
MethodParameters);

   }

   catch (Exception){return null;}

}

}

===========================  ScriptManager class
=======================================
class ScriptManager

{

Hashtable m_Scripts;

List<string> m_ScriptFiles;

string m_sScriptPath;

AppDomain ScriptDomain;

PlugIn plug;

#region Properties

public string ScriptPath

{

get { return m_sScriptPath; }

set { m_sScriptPath = value; }

}

#endregion

#region Constructors

public ScriptManager()

{

   ScriptDomain = AppDomain.CreateDomain("ScriptDomain");

   ScriptPath = String.Empty;

   InitScriptTable();

}

#endregion

#region Procedures

#region Private

/// <summary>

/// Initialise script list

/// </summary>

private void InitScriptTable()

{

string sDLLPath, sScriptDir;

m_ScriptFiles = new List<string>();

m_Scripts = new Hashtable();

// List of script files - Add as required

m_ScriptFiles.Add("TR_TimeAdjuster.cs");

sScriptDir =
Path.Combine(Path.GetDirectoryName(Assembly.GetEntryAssembly().Location),
ScriptPath);

try

{

foreach (string CustomScript in m_ScriptFiles)

{

// Compile and store resource in hashtable

if (File.Exists(Path.Combine(sScriptDir, CustomScript)))

{

sDLLPath = Path.Combine(sScriptDir, String.Concat(CustomScript.Substring(0,
CustomScript.LastIndexOf('.')), ".dll"));

CodeCompile cc = new CodeCompile();

Path.Combine(sScriptDir, CustomScript),

sDLLPath,

CustomScript.Substring(0, CustomScript.LastIndexOf('.'))));

bool res = cc.Compile(Path.Combine(sScriptDir, CustomScript), sDLLPath,
CustomScript.Substring(0, CustomScript.LastIndexOf('.')));

if (res == false)

{

//Add Empty script path in list

m_Scripts.Add(CustomScript.Substring(0, CustomScript.LastIndexOf('.')),
String.Empty);

}

else

{

//Add path of dll

m_Scripts.Add(CustomScript.Substring(0, CustomScript.LastIndexOf('.')),
sDLLPath);

}

}

else

m_Scripts.Add(CustomScript.Substring(0, CustomScript.LastIndexOf('.')),
String.Empty);

}

}

catch (Exception ex )

{throw ex;}

}

#endregion

#region Public

/// <summary>

/// Gets the compiled script for use

/// </summary>

public PlugIn GetScript(string ScriptName)

{

string sDLLPath;

// Script table is empty

if (m_Scripts.Count == 0)

{

InitScriptTable();

}

if (m_Scripts.ContainsKey(ScriptName))

{

sDLLPath = (string)(m_Scripts[ScriptName]);

plug = new PlugIn(sDLLPath, ScriptDomain);

return  plug ;

}

// No script of such name available

return null;

}

public void ClearAllScripts()

{

try

{

m_Scripts.Clear();

plug = null;

AppDomain.Unload(ScriptDomain);

}

catch (Exception ex)

{throw ex;}

}

#endregion

#endregion

}
DeveloperX - 11 Jan 2008 09:01 GMT
> Hi
>
[quoted text clipped - 354 lines]
>
> - Show quoted text -

Yep, that happens if you are marshalling calls across domain
boundaries incorrectly.

There's a little detail here which may help. It's quite a good read
anyway, but search for accessor which is the first time he describes
the problem:

http://www.codeproject.com/KB/cs/dynamicpluginmanager.aspx
Jeff - 11 Jan 2008 12:33 GMT
Thanks for the response. Very interesting article indeed. And similar to
what i want to achieve. I'll try it out :)

========================================================================

On 11 Jan, 09:20, "Jeff" <brede...@yahoo.com> wrote:
> Hi
>
[quoted text clipped - 359 lines]
>
> - Show quoted text -

Yep, that happens if you are marshalling calls across domain
boundaries incorrectly.

There's a little detail here which may help. It's quite a good read
anyway, but search for accessor which is the first time he describes
the problem:

http://www.codeproject.com/KB/cs/dynamicpluginmanager.aspx

Free Magazines

Get these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...

Oracle MagazineNetwork ComputingComputer WorldBio-IT WorldeWeekInformation WeekInfosecurity
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2008 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.