Carregando / descarregando a montagem em diferentes AppDomain

Eu preciso executar um método em um assembly carregado durante o tempo de execução. Agora eu quero descarregar os assemblies carregados após a chamada do método. Eu sei que preciso de um novo AppDomain para poder descarregar as bibliotecas. Mas aqui, o problema surge.

Os assemblies que vão carregar são plugins na minha estrutura de plugins. Eles não têm nenhum ponto de entrada. Tudo o que sei é que eles contêm alguns tipos que implementam uma determinada interface. O código antigo, que não é AppDomain, fica assim (ligeiramente reduzido):

try
{
    string path = Path.GetFullPath("C:\library.dll");
    AppDomain.CurrentDomain.AssemblyResolve += CurrentDomain_AssemblyResolve;
    Assembly asm = Assembly.LoadFrom(path);
    Type[] types = asm.GetExportedTypes();
    foreach (Type t in types)
    {
        if ((t.GetInterface("IStarter") != null) && !t.IsAbstract)
        {
            object tempObj = Activator.CreateInstance(t);
            MethodInfo info = t.GetMethod("GetParameters");
            if (info != null)
            {
                return info.Invoke(tempObj, null) as string;
            }
        }
    }
}
catch (Exception ex)
{
    MessageBox.Show(String.Format("Damn '{0}'.", ex.Message), "Exception", MessageBoxButtons.OK, MessageBoxIcon.Error);
}

private Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args)
{
    if (args.Name.StartsWith("MyProject.View,"))
    {
        string path = Path.GetFullPath("C:\view.dll"));
        return Assembly.LoadFrom(path);
    }
    return null;
}

Agora eu quero que eles carreguem em um AppDomain próprio:

try
{
    string path = Path.GetFullPath("C:\library.dll");
    AppDomain domain = AppDomain.CreateDomain("TempDomain");
    domain.AssemblyResolve += CurrentDomain_AssemblyResolve;  // 1. Exception here!!
    domain.ExecuteAssembly(path);  // 2. Exception here!!
    domain.CreateInstanceFrom(...);  // 3. I have NO clue, how the type is named.
    domain.Load(...);  // 4. I have NO clue, how the assembly is named.
    domain.DoCallBack(...); // 5. Exception here!!
    // ...
}
catch (Exception ex)
{
    MessageBox.Show(String.Format("Damn '{0}'.", ex.Message), "Exception", MessageBoxButtons.OK, MessageBoxIcon.Error);
}

Como você pode ver, eu coloquei em 5 casos.

Se eu definir o manipulador de eventos, receberei uma exceção de que o snap-in do assembly (é um console de gerenciamento (mmc.exe)) não pôde ser encontrado / carregado.

ExecuteAssembly não encontra um ponto de entrada (bem, não há nenhum).

Não tenho idéia de como o tipo é nomeado. Como carregar por interface?

Semelhante ao 3. Como obter o nome de uma montagem?

Mesmo erro que em 1.

Acho que o problema pode ser o console de gerenciamento de alguma forma ou não tenho idéia do que estou fazendo de errado. Qualquer ajuda é apreciada.

ATUALIZAÇÃO 1

Agora tentei usar a solução de proxy postada.

AppDomain domain = AppDomain.CreateDomain("TempDomain");
InstanceProxy proxy = domain.CreateInstanceAndUnwrap(Assembly.GetAssembly(
    typeof(InstanceProxy)).FullName, typeof(InstanceProxy).ToString()) as InstanceProxy;
if (proxy != null)
{
    proxy.LoadAssembly(path);
}
AppDomain.Unload(domain);

public class InstanceProxy : MarshalByRefObject
{
    public void LoadAssembly(string path)
    {
        AppDomain.CurrentDomain.AssemblyResolve += CurrentDomain_AssemblyResolve;
        Assembly asm = Assembly.LoadFrom(path);
        Type[] types = asm.GetExportedTypes();
        // ...see above...
    }
}

Isso também não funciona. Ao tentar criar o objeto proxy, recebo uma exceção:

Não foi possível carregar o arquivo ou assembly 'MyProject.SnapIn, Versão = 1.0.0.0, Culture = neutral, PublicKeyToken = null' ou uma de suas dependências. O sistema não pode encontrar o arquivo especificado.

O arquivo na mensagem de erro está carregado no mmc (o SnapIn). Alguma idéia de como corrigir esse erro? AppDomain.AssemblyResolve não é chamado (nem no domínio antigo nem no novo).

ATUALIZAÇÃO 2

Agora eu tentei a solução com o AppDomainSetup. Agora, a exceção foi alterada para:

Não foi possível carregar o arquivo ou montagem 'file: /// C: /Development/MyProject/bin/SnapIn/MyProject.SnapIn.DLL' ou uma de suas dependências. O nome do assembly ou a base de código fornecida era inválida. (Exceção de HRESULT: 0x80131047)

Qualquer ideia?

questionAnswers(3)

yourAnswerToTheQuestion