[C#] serialization issue with dynamically loaded assembly

Pagina: 1
Acties:

Onderwerpen


Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
Ik probeer items van een Entity Class te serializen naar XML, de code doet zijn werk onder normale omstandigheden, maar als ik de Assembly waar de Entity in zit dynamisch laad krijg ik een error:

calling code in de exe, werkt als 1e lijn niet in commentaar, en dus de functie niet gebruikt wordt:
(code wat ingeknipt voor readability)
C#:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
      
      // main applicatie   
       private void button_Click(object sender, RoutedEventArgs e)
        {
            //CBackup.CBackup.AppCloseBackup(); // --> werkt als uncommented
            BackupByRef();                                     // --> throw error
        }

        private void BackupByRef()
        {
            const string AssName = @"T:\CWPFPROJECT\CBackup\bin\Debug\CBackup";

            MethodInfo mi = null;
            Type type = null;

                //Load assembly & query info
                Type[] ts = Assembly.LoadFrom(AssName + ".dll").GetExportedTypes();

                for (int i = 0; i < ts.Count(); i++)
                {
                    type = ts[i];
                    if (type.Name == "CBackup")
                    {
                        break;
                    }
                }
                mi = type.GetMethod("AppStartBackup");
                object returnObject = mi.Invoke(null, null);
                MessageBox.Show(((bool)returnObject).ToString());


de assembly
C#:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
        public static bool AppStartBackup()
        {
            WolBackup wb = new WolBackup();
            wb.MakeBackup();
            return true;
        }

//knip  from class wolbackup

       public void MakeBackup()
        {
            var q = from l in ent.WolLijst   // ent = Entity framework 
                    select l;
            if (q.Count() > 0)
            {
                List<WolBackup> lw = q.ToList();
                FileStream fs = new FileStream(@"T:\test.xml", FileMode.OpenOrCreate);
                XmlSerializer s = new XmlSerializer(typeof(List<WolBackup>));
                try
                {
                    s.Serialize(fs, lw);
                }
                catch (System.InvalidOperationException ex)
                {
                    MessageBox.Show(ex.InnerException.Message + " " + ex.Message);
                }
                fs.Close();
            }
      }


geeft dus bij dynamisch laden van de dll :

(ex.message)
There was an error generating the XML document.

(ex.innerexception.message)
[A]System.Collections.Generic.List`1[CBackup.WolBackup] cannot be cast to [B]System.Collections.Generic.List`1[CBackup.WolBackup]. Type A originates from 'mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089' in the context 'LoadNeither' at location 'C:\Windows\assembly\GAC_32\mscorlib\2.0.0.0__b77a5c561934e089\mscorlib.dll'. Type B originates from 'mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089' in the context 'LoadNeither' at location 'C:\Windows\assembly\GAC_32\mscorlib\2.0.0.0__b77a5c561934e089\mscorlib.dll'.

waar zitten de C# / .NET experts , want ik raak er niet uit :'(

Acties:
  • 0 Henk 'm!

  • beany
  • Registratie: Juni 2001
  • Laatst online: 17-09 13:56

beany

Meeheheheheh

Ik zal vast wat kippig zijn, maar ik kan niet echt bepalen wat je nou eigenlijk probeert te doen. Volgens mij mist er ook het 1 en het ander aan code om duidelijk te maken wat je doet en waarom het eventueel mis gaat.

En wat gebeurt er tijdens debuggen? Wat is, als je een breakpoint zet op de s.Serialize(fs, lw);, de waarde van 'lw' ? Staan er items in? Kan je die gewoon zien in de debugger?

Dagelijkse stats bronnen: https://x.com/GeneralStaffUA en https://www.facebook.com/GeneralStaff.ua


Acties:
  • 0 Henk 'm!

  • whoami
  • Registratie: December 2000
  • Laatst online: 01:56
Ben je zeker dat je de juiste versie van die assembly die je dynamisch laadt, hebt ?
Heb je die file geserialized met een oude versie van je programma oid ?

Waar krijg je die exception precies ? Bij het serializeren ?

Ik vind het trouwens wel heel gek hoe je dat hier probeert te doen ...
Je haalt een type uit een bepaalde assembly, en invoked een bepaalde method ... Gek.
Waarom doe je het zo ? Waarom niet netter ? Dit is gewoon een fail to happen in de toekomst; je doet heel wat aannames, bv dat dat type in die assembly zit, en dat die een bepaalde method heeft.
Waarom ga je hier niet met een factory gaan werken die je een instance van dat type gaat teruggeven (of een interface die moet geimplementeerd worden door dat type), en dan een bpeaalde method gaan aanroepen , ipv alles met reflection te willen doen (en daardoor al die type en methodnamen hard-coded als string constants te moeten opnemen).

En ik zie ook niet wat die 2 stukjes code met elkaar te maken hebben ? :?

https://fgheysels.github.io/


Acties:
  • 0 Henk 'm!

  • H!GHGuY
  • Registratie: December 2002
  • Niet online

H!GHGuY

Try and take over the world...

Probeer eens de individuele instances van je WolBackup te serializen. Waarschijnlijk ligt daar de echte fout en wordt de exceptie gemaskeerd door gebruik van List<WolBackup>.

ASSUME makes an ASS out of U and ME


Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
hmm... misschien was het gisteren toch wat laat , even wat verduidelijking:

- wat ik probeer te doen: een (deel van een) sql tabel serializen naar xml, ik ga naar SQL server via 't Entity Framework (VS 2008 sp 1)

button1_click :
- werkt zonder problemen als ik een reference in mijn main app heb naar de assembly die het serializen uitvoert , gebruik dan CBackup.AppCloseBackup(); ,
-throwt de System.InvalidOperationException bij s.Serialize als ik via de functie en reflection de assembly laad

- die Factory ga ik eens bekijken, (ben nog relatief nieuw in .net). Voorwaarde die alles zo gecompliceerd maakt is dat de assembly niet gereferenced mag / kan worden vanuit de main app. @design time, maar als'k dit kan bereiken met een Factory en interfaces te definieren is dit missch een betere optie.

- even een individuele instance serializen is idd missch. een nuttige test

alvast bedankt voor jullie input

[ Voor 9% gewijzigd door Verwijderd op 05-08-2009 08:06 ]


Acties:
  • 0 Henk 'm!

  • Sebazzz
  • Registratie: September 2006
  • Laatst online: 16-09 15:42

Sebazzz

3dp

Verwijderd schreef op woensdag 05 augustus 2009 @ 08:03:
die Factory ga ik eens bekijken, (ben nog relatief nieuw in .net).
Factory is niet iets van .NET maar gewoon een design pattern in software development ;) Factory werkt cross-taal, van C++ tot PHP (5+).

[Te koop: 3D printers] [Website] Agile tools: [Return: retrospectives] [Pokertime: planning poker]


Acties:
  • 0 Henk 'm!

  • creator1988
  • Registratie: Januari 2007
  • Laatst online: 20:55
Waarom mag je eigenlijk die assembly niet referencen in je main project ?

Je kunt ook een interface maken in je main project, en dit project referencen vanuit het project waaruit je de assembly genereert. Vervolgens de entity class de interface laten implementeren, dan kan je gewoon naar de interface casten als je een object deserialized.

Acties:
  • 0 Henk 'm!

  • whoami
  • Registratie: December 2000
  • Laatst online: 01:56
Verwijderd schreef op woensdag 05 augustus 2009 @ 08:03:
hmm... misschien was het gisteren toch wat laat , even wat verduidelijking:

- die Factory ga ik eens bekijken, (ben nog relatief nieuw in .net). Voorwaarde die alles zo gecompliceerd maakt is dat de assembly niet gereferenced mag / kan worden vanuit de main app. @design time, maar als'k dit kan bereiken met een Factory en interfaces te definieren is dit missch een betere optie.
Doe dat. :)
Dan kan je dit doen:
Laad je assembly dynamisch dmv reflection; zoek in die assembly een type die jouw IFactory interface implementeert; instantieer een instance van dat type, en dan roep je gewoon de juiste method van die interface op.
Simpel gezegd, zou het zo iets moeten zijn:

code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
Assembly a = Assembly.LoadFrom (@"....");

Type[] types = a.GetTypes();

IMyFactoryInterface factoryInstance = null;

foreach( Type t in types )
{
    if( typeof (IMyFactoryInterface).IsAssignableFrom (t) )
    {
         factoryInstance = Activator.CreateInstance (t) as IMyFactoryInterface;
         break;
    }
}

if( factoryInstance == null )
{
   throw new Exception("geen IMyFactoryInterface gevonden");
}

Bliep b = factoryInstance.CreateBliep();


Zoiets ongeveer.

https://fgheysels.github.io/


Acties:
  • 0 Henk 'm!

  • creator1988
  • Registratie: Januari 2007
  • Laatst online: 20:55
Wat whoami zegt, ongeveer de standaardmanier om pluginsystemen etc. te maken in .Net
Pagina: 1