Динамическая сборка, компиляция и загрузка
Я собираю сборку во время выполнения и связываю ее, добавляя в новый домен. Я использую его, а затем выгружаю домен. Но когда я пытаюсь снова скомпилировать во время того же запуска, я не могу получить доступ к этой сборке, потому что она используется в данный момент.
Вот некоторые из моего кода
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.