Динамическая сборка, компиляция и загрузка

Я собираю сборку во время выполнения и связываю ее, добавляя в новый домен. Я использую его, а затем выгружаю домен. Но когда я пытаюсь снова скомпилировать во время того же запуска, я не могу получить доступ к этой сборке, потому что она используется в данный момент.

Вот некоторые из моего кода

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ClassLibrary2
{
    public interface IExtension
    {
        String GetExtensionName();
    }
}

Моя сборка

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using ClassLibrary2;

namespace ClassLibrary1
{
    public class Extension1 : MarshalByRefObject, IExtension
    {
        public Extension1()
        {
        }

        public string GetExtensionName()
        {
            return "Extension 1 from " + AppDomain.CurrentDomain.FriendlyName;
        }
    }
}

И приложение, которое использует его

namespace ConsoleApplication7
{
    class Program
    {
        static IEnumerable<IExtension> extensions;
        static void Main(string[] args)
        {
            // Create app domain
            AppDomain domain = CreateDomain(Directory.GetCurrentDirectory());
            try
            {
                // Get extensions
                extensions = EnumerateExtensions(domain);
                foreach (IExtension extension in extensions)
                    // Execute extension method in separate domain.
                    Console.WriteLine(extension.GetExtensionName());

                // Unload domain

                UnloadDomain(domain);
            }
            finally
            {
                domain = null;
                GC.Collect(2);
                extensions = null;
            }

            Console.ReadKey();
        }            

        private static IEnumerable<IExtension> EnumerateExtensions(AppDomain domain)
        {
            IEnumerable<string> fileNames = Directory.EnumerateFiles(domain.BaseDirectory, "*.dll");
            if (fileNames != null)
            {
                foreach (string assemblyFileName in fileNames)
                {
                    foreach (string typeName in GetTypes(assemblyFileName, typeof(IExtension), domain))
                    {
                        System.Runtime.Remoting.ObjectHandle handle;
                        try
                        {
                            handle = domain.CreateInstanceFrom(assemblyFileName, typeName);
                        }
                        catch (MissingMethodException)
                        {
                            continue;
                        }
                        object obj = handle.Unwrap();
                        IExtension extension = (IExtension)obj;
                        yield return extension;
                    }
                }
            }

        }    

        private static IEnumerable<string> GetTypes(string assemblyFileName, Type interfaceFilter, AppDomain domain)
        {
            Assembly asm = domain.Load(AssemblyName.GetAssemblyName(assemblyFileName));
            Type[] types = asm.GetTypes();
            foreach (Type type in types)
            {
                if (type.GetInterface(interfaceFilter.Name) != null)
                {
                    yield return type.FullName;
                }
            }
        }    

        static AppDomain CreateDomain(string path)
        {
            AppDomainSetup setup = new AppDomainSetup();
            setup.ApplicationBase = path;
            return AppDomain.CreateDomain("Temporary domain", null, setup);
        }    

        static void UnloadDomain(AppDomain domain)
        {            
            AppDomain.Unload(domain);
        }
    }
}

Так в Main() во время Console.ReadKey(); сборка все еще заблокирована, и я не могу получить к ней доступ (например, не могу удалить ее через Windows).

Есть ли способ решить это?

2 ответа

Решение

Хорошо, я решил эту проблему. Я использовал теневое копирование, просто настроил теневое копирование в этом другом домене, и у меня это сработало.

Я думаю domain.Load подключает сборку к вашей программе, попробуйте загрузить внутри Extension1 попытаться переместить GetTypes к классу Extension1

Не помню но думаю domain.Load просто бежит Assembly.LoadFrom( и вот что подключает ваше приложение к DLL.

Другие вопросы по тегам