private void button1_Click(object sender, EventArgs e) { Assembly assembly = Assembly.LoadFile(@"C:\testlib.dll"); label1.Text = assembly.FullName; }
固然,顺序实行一般,您不会发明任何编译时或运转时的毛病。但是,当你在没有退出此顺序之前,再去编译被挪用的testlib.dll,你会发明,Visual Studio没法完成编译,提醒说该文件正在被别的的历程所运用。
事实上,我们的顺序与这个testlib.dll并没有太大的关联,我们的顺序只不过就是显现一下testlib.dll的基本信息。假如testlib.dll是一个同享的库,那末资本独有题目会影响到别的顺序的一般事情。
Assembly没有Unload的功用,但可以运用AppDomain来处置惩罚这个题目。基本思路是,建立一个新的AppDomain,在这个新建的AppDomain中装载assembly,挪用个中的要领,然后将取得的效果返回。在完成一切操纵今后,挪用AppDomain.Unload要领卸载这个新建的AppDomain,如许也同时卸载了assembly。注重:你没法将装载的assembly直接返回到当前应用顺序域(AppDomain)。
起首,建立一个RemoteLoader,这个RemoteLoader用于在新建的AppDomain中装载assembly,并向外宣布一个属性,以便外界可以取得assembly的FullName。RemoteLoader须要继续于MarshalByRefObject。代码以下:
public class RemoteLoader : MarshalByRefObject { private Assembly assembly; public void LoadAssembly(string fullName) { assembly = Assembly.LoadFrom(fullName); } public string FullName { get { return assembly.FullName; } } }
其次,建立一个LocalLoader。LocalLoader的功用是建立新的AppDomain,然后在这个新的AppDomain中挪用RemoteLoader,以便经由历程RemoteLoader来建立assembly并取得assembly的相干信息。此时被挪用的assembly天然被装载于新的AppDomain中。末了,LocalLoader还须要供应一个新的要领,就是AppDomain的卸载。代码以下:
public class LocalLoader { private AppDomain appDomain; private RemoteLoader remoteLoader; public LocalLoader() { AppDomainSetup setup = new AppDomainSetup(); setup.ApplicationName = "Test"; setup.ApplicationBase = AppDomain.CurrentDomain.BaseDirectory; setup.PrivateBinPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "private"); setup.CachePath = setup.ApplicationBase; setup.ShadowCopyFiles = "true"; setup.ShadowCopyDirectories = setup.ApplicationBase; appDomain = AppDomain.CreateDomain("TestDomain", null, setup); string name = Assembly.GetExecutingAssembly().GetName().FullName; remoteLoader = (RemoteLoader)appDomain.CreateInstanceAndUnwrap( name, typeof(RemoteLoader).FullName); } public void LoadAssembly(string fullName) { remoteLoader.LoadAssembly(fullName); } public void Unload() { AppDomain.Unload(appDomain); appDomain = null; } public string FullName { get { return remoteLoader.FullName; } } }
末了,修正我们WinForm上的Button Click事宜处置惩罚历程,改成以下的情势:
private void button1_Click(object sender, EventArgs e) { LocalLoader ll = new LocalLoader(); ll.LoadAssembly(@"C:\testlib.dll"); label1.Text = ll.FullName; ll.Unload(); }
在完成上述的修正后,我们的顺序也一样可以正确地显现assembly的FullName,而且,在显现完assembly信息后,顺序会主动卸载新建的AppDomain,以防备testlib.dll的资本独有,影响别的顺序的运转。
以上就是AppDomain与Assembly的动态加载与卸载代码详解的细致内容,更多请关注ki4网别的相干文章!