Avatar billede Slettet bruger
05. juni 2005 - 00:50 Der er 16 kommentarer og
1 løsning

Problemer med at cast et object efter load via appDomain

Hey

Jeg har et lille prob.

Dette her kan jeg godt:
------
o = appDomain.CreateInstance("Test_Server",
"Server.ServerJob1", false,BindingFlags.CreateInstance,
null, new object[] {},
null, null, null );

Form x = (Form)o.Unwrap();
x.Show();
------

Men dette kan jeg ikke:
------

o = appDomain.CreateInstance("Test_Server",
"Server.ServerJob", false,BindingFlags.CreateInstance,
null, new object[] {},
null, null, null );

ServerJob test = (ServerJob)o.Unwrap();
test.TestMe(); <--- Specified cast is not valid.
------

Og det er selv om at jeg har denne type object i min dll som jeg loader dynamisk.. har ingen ide til hvorfor den ikke vil, hvad er det ved en Form den forstår og ikke min egen type objekt?

På forhånd tak
Avatar billede driis Nybegynder
05. juni 2005 - 01:08 #1
er du sikker på at det er i linien
test.TestMe();

Du får exception'en ? For i så fald bør det jo næsten være noget i TestMe metoden, der fejler.
Avatar billede arne_v Ekspert
05. juni 2005 - 10:57 #2
det må logisk set være i linien ovenover !
Avatar billede arne_v Ekspert
05. juni 2005 - 10:58 #3
extender ServerJob MarshalByRefObject ?

(jeg kan ikke huske fejlen hvis den ikke gør)
Avatar billede Slettet bruger
05. juni 2005 - 11:54 #4
hey.. i har fuldstændigt ret, det er naturligvis
ServerJob test = (ServerJob)o.Unwrap();
som giver fejl.. :) det blev lidt sent i går.
Nej ServerJob extender ikke MarshalByRefObject, har du et eksempel?
Avatar billede Slettet bruger
05. juni 2005 - 12:51 #5
hmm.. har lige fundet ud af at selv om jeg laver appDomain.CreateInstance i stedet for Assembly.Load så kan jeg stadig ikke unloade min dll.. det var det som var formålet med det hele.. nogen som har en ide til hvad jeg kan gøre?
Avatar billede arne_v Ekspert
05. juni 2005 - 14:47 #6
Klasser du tilgår i et andet app domain skal arve fra MarshalByRefObject.

Med appDomain.CreateInstance kan du godt unloade din klasse. Men
ServerJob test = (ServerJob)o.Unwrap() har jo også ServerJob klassen i
current app domain, hvilket nok ikke er meningen.
Avatar billede arne_v Ekspert
05. juni 2005 - 14:48 #7
jeg lavede det her eksempel for nogle måneder siden:

using System;
using System.Reflection;
using System.CodeDom.Compiler;

using Microsoft.CSharp;

namespace E
{
    class MainClass
    {
        public static void Main(string[] args)
        {
            string code1 = @"
using System;

public class X : MarshalByRefObject
{
    public override string ToString()
    {
        return ""X1"";
    }
}";
            string code2 = @"
using System;
public class X : MarshalByRefObject
{
    public override string ToString()
    {
        return ""X2"";
    }
}";
            ICodeCompiler c = new CSharpCodeProvider().CreateCompiler();
            CompilerParameters cp = new CompilerParameters();
            cp.ReferencedAssemblies.Add("System.dll");
            cp.GenerateInMemory = false;
            cp.OutputAssembly = "X.dll";
            CompilerResults cr1 = c.CompileAssemblyFromSource(cp, code1);
            AppDomain d1 = AppDomain.CreateDomain("Dom1");
            object x1  = d1.CreateInstanceAndUnwrap("X", "X");
            Console.WriteLine(x1);
            AppDomain.Unload(d1);
            CompilerResults cr2 = c.CompileAssemblyFromSource(cp, code2);
            AppDomain d2 = AppDomain.CreateDomain("Dom2");
            object x2  = d2.CreateInstanceAndUnwrap("X", "X");
            Console.WriteLine(x2);
            AppDomain.Unload(d2);
        }
    }
}
Avatar billede Slettet bruger
05. juni 2005 - 15:15 #8
Hey tak for dit eksembel.. men hvad nu hvis jeg tilføjer følgende til code1:
----

public void TestMe() {
Console.WriteLine(""Test is a test"");
}

----

hvordan får jeg så den kørt?
Avatar billede arne_v Ekspert
05. juni 2005 - 15:21 #9
2 muligheder:

1)  reflection

2)  lade de klasser du loader implementere et interface som er fast og kendt
    i main app domain
Avatar billede Slettet bruger
05. juni 2005 - 15:36 #10
jeg har lige prøvet det med at lave et interface til dem, men får igen fejl med at de ikke kan caste det.
kan du give et eksempel på hvordan jeg skal lave det?
på forhånd tak
Avatar billede arne_v Ekspert
05. juni 2005 - 16:24 #11
jeg prøver at lave et eksempel
Avatar billede arne_v Ekspert
05. juni 2005 - 16:33 #12
namespace E.Interface
{
    public interface IX
    {
        string WhoAmI();
    }
}
Avatar billede arne_v Ekspert
05. juni 2005 - 16:34 #13
using System;
using System.Reflection;
using System.CodeDom.Compiler;

using Microsoft.CSharp;

using E.Interface;

namespace E.Demo
{
    class MainClass
    {
        public static void Main(string[] args)
        {
            string code1 = @"
using System;
using E.Interface;

public class X : MarshalByRefObject, IX
{
    public override string ToString()
    {
        return ""X1"";
    }
    public string WhoAmI()
    {
        return ""I am X1"";
    }
}";
            string code2 = @"
using System;
using E.Interface;

public class X : MarshalByRefObject, IX
{
    public override string ToString()
    {
        return ""X2"";
    }
    public string WhoAmI()
    {
        return ""I am X2"";
    }
}";
            ICodeCompiler c = new CSharpCodeProvider().CreateCompiler();
            CompilerParameters cp = new CompilerParameters();
            cp.ReferencedAssemblies.Add("System.dll");
            cp.ReferencedAssemblies.Add("IX.dll");
            cp.GenerateInMemory = false;
            cp.OutputAssembly = "X.dll";
            CompilerResults cr1 = c.CompileAssemblyFromSource(cp, code1);
            AppDomain d1 = AppDomain.CreateDomain("Dom1");
            object x1  = d1.CreateInstanceAndUnwrap("X", "X");
            Console.WriteLine(x1);
            Console.WriteLine(((IX)x1).WhoAmI());
            AppDomain.Unload(d1);
            CompilerResults cr2 = c.CompileAssemblyFromSource(cp, code2);
            AppDomain d2 = AppDomain.CreateDomain("Dom2");
            object x2  = d2.CreateInstanceAndUnwrap("X", "X");
            Console.WriteLine(x2);
            Console.WriteLine(((IX)x2).WhoAmI());
            AppDomain.Unload(d2);
        }
    }
}
Avatar billede arne_v Ekspert
05. juni 2005 - 16:34 #14
C:\e6>csc /t:library IX.cs
Microsoft (R) Visual C# .NET Compiler version 7.10.6001.4
for Microsoft (R) .NET Framework version 1.1.4322
Copyright (C) Microsoft Corporation 2001-2002. All rights reserved.


C:\e6>csc /r:IX.dll E.cs
Microsoft (R) Visual C# .NET Compiler version 7.10.6001.4
for Microsoft (R) .NET Framework version 1.1.4322
Copyright (C) Microsoft Corporation 2001-2002. All rights reserved.


C:\e6>e
X1
I am X1
X2
I am X2
Avatar billede Slettet bruger
05. juni 2005 - 17:02 #15
Hey.. det ser ud til at virke.. jeg tester lige med det jeg havde lavet før.. du må lige oprette et svar hvis du vil have de points.. og ellers rigtigt mange tak for hjælpen :)
Avatar billede Slettet bruger
05. juni 2005 - 17:16 #16
Hey Arne.. Har lige lavet min egen kode om til det du sendte, og det virker som det skal :) så kan jeg endelig komme videre med resten af mit system..
igen mange tak.. og også tak de andre gange du har hjulpet :)
Avatar billede arne_v Ekspert
05. juni 2005 - 18:34 #17
svar
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
IT-kurser om Microsoft 365, sikkerhed, personlig vækst, udvikling, digital markedsføring, grafisk design, SAP og forretningsanalyse.

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester

IT-JOB