卸载AppDomain

时间:2014-08-06 11:31:26

标签: c# .net .net-assembly appdomain

有没有办法卸载父AppDomain?
我试图在我的新AppDomain中加载不同版本的程序集,但它继续从父域加载版本。当我在新的AppDomain中加载程序集时,我显示正确的路径 或者也许还有另一种方法可以做到这一点?

提前致谢。
修改

AppDomain MailChimpDomain = AppDomain.CreateDomain("MailChimpDomain");
string path = AppDomain.CurrentDomain.BaseDirectory + "ServiceStack_V3\\ServiceStack.Text.dll";
MailChimpDomain.Load(AssemblyName.GetAssemblyName(path));



EDIT2
代码2:

var MailDom = AppDomain.CreateDomain("MailChimpDomain");
            MailDom.AssemblyLoad += MailDom_AssemblyLoad;
            MailDom.AssemblyResolve += new ResolveEventHandler(MailDom_AssemblyResolve);
            MailDom.DoCallBack(() =>
            {

                string name = @"ServiceStack.Text.dll";
                var assembly = AppDomain.CurrentDomain.Load(name);
                string name2 = @"MailChimp.dll";
                var assembly2 = AppDomain.CurrentDomain.Load(name2);

                //mailChimp object with API key found in mailChimp profile
                MailChimp.MailChimpManager mc = new MailChimp.MailChimpManager("111111111111222f984b9b1288ddf6f0-us1");
                //After this line there are both versions of ServiceStack.Text Assembly
                MailChimp.Helper.EmailParameter em = new MailChimp.Helper.EmailParameter();
                em.Email = strEmailTo;

                //Creating email parameters
                string CampaignName = "Digest for " + strEmailTo + " " + DateTime.Now.ToShortDateString();
                MailChimp.Campaigns.CampaignCreateOptions opt = new MailChimp.Campaigns.CampaignCreateOptions();
                opt.ListId = "l338dh";
                opt.Subject = strSubject;
                opt.FromEmail = strEmailFrom;
                opt.FromName = strNameFrom;
                opt.Title = CampaignName;

                //creating email content
                MailChimp.Campaigns.CampaignCreateContent content = new MailChimp.Campaigns.CampaignCreateContent();
                content.HTML = strEmailContent;

                //Creating new email and sending it
                MailChimp.Campaigns.CampaignFilter par = null;
                MailChimp.Campaigns.CampaignSegmentOptions SegOpt = null;
                MailChimp.Campaigns.CampaignTypeOptions typeOpt = null;

                mc.CreateCampaign("regular", opt, content, SegOpt, typeOpt);
                MailChimp.Campaigns.CampaignListResult camp2 = mc.GetCampaigns(par, 0, 5, "create_time", "DESC");
                foreach (var item in camp2.Data)
                {
                    if (item.Title == CampaignName)
                    {
                        mc.SendCampaign(item.Id);
                        break;
                    }
                }

            });
static Assembly MailDom_AssemblyResolve(object sender, ResolveEventArgs args)
        {
            byte[] rawAssembly = File.ReadAllBytes(Path.Combine(path, args.Name));
            return Assembly.Load(rawAssembly);
        }

2 个答案:

答案 0 :(得分:1)

您的代码实际上做的是将程序集加载到您的父域。如果要将程序集加载到子域中,则必须从子域内部执行此操作。这是一种鸡蛋问题,因为父程序集(将子程序集加载到子域中)也必须加载到子域中才能执行。

假设您有一个名为MyAssembly.dll的控制台应用程序和程序集的简单示例,可以这样做:

static void Main(string[] args) {
  var domain = AppDomain.CreateDomain("MailChimpDomain");
  domain.AssemblyResolve +=new ResolveEventHandler(domain_AssemblyResolve);
  domain.DoCallBack(() => {
    string path = @"MyAssembly.dll";
    var assembly = AppDomain.CurrentDomain.Load(path);

    // to do something with the assembly
    var type = assembly.GetType("MailChimp.MailChimpManager");
    var ctor = type.GetConstructor(new[] { typeof(string) });
    var mc = ctor.Invoke(new object[] { "111111111111222f984b9b1288ddf6f0" });        
  });
}

static Assembly domain_AssemblyResolve(object sender, ResolveEventArgs args) {
  byte[] rawAssembly = File.ReadAllBytes(Path.Combine(@"c:\MyAssemblyPath", args.Name));
  return Assembly.Load(rawAssembly);
}

在这种情况下,子域具有相同的根目录,用于将程序集解析为父域(因此它可以执行加载" MyAssembly.dll")的代码。

如果使用反射的代码长于此值,您可以考虑使用bootstrapper。 I.E.你创建了一个名为MyBootstrapper.dll的新库,你可以从MyBootstrapper.dll直接引用你喜欢的ServiceStack.Text.dll和MailChimp.dll版本,然后你将创建引导类 - 让我们调用它{{1这将是静态的,并且将具有一个名为Bootstrapper的单一公共静态方法,它将执行脏工作。

然后在Run方法中,您将调用此引导程序。

DoCallBack()

答案 1 :(得分:0)

不,您可能无法卸载默认AppDomain或默认AppDomain中加载的任何程序集。

但是,您可以执行的操作是在两个子域中加载两个版本的ServiceStack程序集。你应该可以卸载它们中的任何一个。但是,使用这些域中的类型可能比平时更难。您必须通过远程处理来完成此操作。

考虑到这会产生的开销,您应该考虑只使用该程序集的一个版本(即使这意味着要调整应用程序的一部分,即在默认域中运行的应用程序)。