Laden...

Assemblies und Versionen

Erstellt von s4rge vor 7 Jahren Letzter Beitrag vor 7 Jahren 2.879 Views
S
s4rge Themenstarter:in
69 Beiträge seit 2007
vor 7 Jahren
Assemblies und Versionen

Hallo,

ich habe mal eine Grundlagen frage:

Wie bekommt man es hin, dass man Teile zu verschieben Assembly Versionen nutzen kann?

Beispiel
Für einen Socket Server habe ich ein Interface entworfen das ein "Protokoll" sein soll. Sagen wir es wurde mit Version 1.0.0.0 erstellt. Zusätzlich habe ich mir einen Test Client geschrieben der dieses Interface nutzt (per Projekt Referenz)

Nun habe ich den Socket Server auf .net 4 und auf eine höhere Version geändert (3.2.x.x)
Wenn ich nun versuche den TestClient mit dem Server kommunizieren zulassen bekomme ich eine Exception, dass der Type mit eine anderen Asm version erstellt wurde.

Für die Serialisierung benutze ich einen BinaryFormater.

Kann man diese Problematik irgendwie lösen, dem Client Projekt eine Referenz auf die höhere Version zu geben? Beim Googlen hatte ich eine doch eher umständliche Custom Serialization in Verbindung mit Versioning .. das Beispiel habe ich leider gerade nicht parat, könnte ich allerdings nachreichen.

MfG

6.911 Beiträge seit 2009
vor 7 Jahren

Hallo s4rge,

Test Client ... (per Projekt Referenz)

Wenn du dann in VS die .net-Version vom Server änderst, so passt das beim Build od. es kommt dort schon ein Fehler.

Ich will hier keine kurze Antwort, geben da ich meine dass das nötige Hintergrundwissen dazu nicht schadet. Lies dir daher What's New in .NET 2.0 for Assemblies and Versioning? (ist soweit ich weiß immer noch aktuell) und Redirecting Assembly Versions durch, dann sollte deine Frage geklärt sein und du eine Menge über Assembly-Versionen in .net gelernt haben 😉

mfG Gü

Stellt fachliche Fragen bitte im Forum, damit von den Antworten alle profitieren. Daher beantworte ich solche Fragen nicht per PM.

"Alle sagten, das geht nicht! Dann kam einer, der wusste das nicht - und hat's gemacht!"

W
872 Beiträge seit 2005
vor 7 Jahren

Ich würde Dir dringend empfehlen, etwas anderes als Binary Formatter zu nehmen.
Ich persönlich benutze Protocol-Buffer via protobuf-net.
Binary Formatter ist langsam - auch ein zusätzliches Feld wirft ihn aus der Bahn....

S
s4rge Themenstarter:in
69 Beiträge seit 2007
vor 7 Jahren

Hi,

danke für die Antworten

@gfoidl ich lese es mir später mal durch
@weismat .. darüber hatte ich auch schon mal nach gedacht. Allerdings würde ich lieber bei Bordmitteln bleiben, dort ist die Auswahl nur sehr sperrlich. Ich werde mir deinen Vorschlag aber gerne mal ansehen.. für neues bin ich natürlich immer offen.

MfG

16.842 Beiträge seit 2008
vor 7 Jahren

Boardmittel werden Dich hier eher bremsen als weiter bringen. Protobuf ist schon eine sehr gute und weit verbreitete Basis.
Boardmittel muss man in Zeiten von Open Source sowieso etwas differenzieren.
Microsoft selbst empfiehlt bei vielen Dingen mittlerweile etablierte Community Projekte.

W
872 Beiträge seit 2005
vor 7 Jahren

Bei der Serialisierung setzt MS selber auf Bond.
Protobuf-Net finde ich etwas einfacher, weil man kein Schema braucht und auch keinen zusätzlichen Precompile, sondern rein mit Code Annotations analog dem Binary Formatter arbeitet.

S
s4rge Themenstarter:in
69 Beiträge seit 2007
vor 7 Jahren

Hallo,

protobuf hab ich mir jetzt schon nen paar Tage angesehen. Allerdings bleibe ich immer wieder an einer Stelle hängen, die sich scheinbar nicht damit lösen lässt.

Ich "brauche" als Nutzdaten etwas "Universelles", dass hab ich bis dato über object gelöst. Da aber pb aber mit object nicht klar kommt, habe ich natürlich ein Problem.
Nutze ich ein Inteface oder Abstrackt Klasse müssen beiden Seiten die Typen bekannt sein und es muss ja noch über Include gebunden werden.
Gibts dafür auch eine andere Lösung? Sprich eine Art dyn. Include?

MfG

W
872 Beiträge seit 2005
vor 7 Jahren

Bei mir besteht ein Protokoll immer aus einem Kopf und der eigentlichen Nachricht.
Der Kopf enthält Länge, Nachrichtentyp und Versionsnummer.
Die eigentliche Nachricht ist dann in der abstrakten Basisklasse ein Byte Array. Jede Nachricht selbst muss dann eine ToByte Methode implementieren und hat eine statische Factory-Methode FromBytes.
Hilft Dir das?

S
s4rge Themenstarter:in
69 Beiträge seit 2007
vor 7 Jahren

Grundsätzlich habe ich das schon mal so oder so änhlich gebaut.

Was ich ehrlich gesagt nicht verstehe ist wie man das mit protobuf aufbaut. Das "Person" Beispiel was so heufig herangezogen wird ist in dem context auch nicht wirklich hilfreich.

@weismat: Im Grunde denke ich das dein Ansatz der richtig ist, allerdings habe ich gerade etwas verständnis schwierigkeiten wie ich das mit pb verheiraten soll. Ich habe z.B. das
hier gefunden.

Ich will auch Dateien anhängen, mit Base64 würde man es ja nur aufblähen.

Mein Strutkur soll ca so sein:

public class ProtoNetMessageItem<T>:ProtoNetMessageItemBase {
        [ProtoMember(1)]
        public T Value
        {
            get;
            internal set;
        }
        [ProtoMember(2)]
        public string ValueKey { get; internal set; }
        [ProtoMember(3)]
        public uint SequenzId { get; internal set; }
        [ProtoMember(4)]
        public uint SequenzLastId { get; internal set; }
    }

das ist an das Bsp mit dem Link angelehnt. Irgendwie steh ich gerade nur bissel aufm schlauch wie man mit dem byte[] hinbekommen soll.
Jemand nen Tip?

MfG

W
872 Beiträge seit 2005
vor 7 Jahren

        public byte[] ToProtobuf()
        {
            using (var memoryStream = new MemoryStream()) {
               Serializer.Serialize(memoryStream, this);
               return memoryStream.ToArray();
            }
        }

public static MeineKlasse FromBytes(byte[] bytes)
        {
            using (var memoryStream = new MemoryStream(bytes)) {
               var result = Serializer.Deserialize<MeineKlasse >(memoryStream);
               return result;
             }
        }

Angepasst an Abts berechtigten Hinweis...

16.842 Beiträge seit 2008
vor 7 Jahren

usings nicht vergessen.

3.003 Beiträge seit 2006
vor 7 Jahren

Nur ergänzend zu weismat, weil es sich oft besser macht, auf Streams zu arbeiten:


[ProtoContract]
class MyClass
{
    //...
        public static MyClass Create(Stream stream) => Serializer.Deserialize<Person>(stream);
}
static class MyClassExtensions
{
        public static Stream GetStream(this MyClass myClass)
        {
            var result = new MemoryStream();
            Serializer.Serialize(result, person);
            result.Position = 0;
            return result;
        }
}
//Anwendung
//schreiben
using (var stream = myClassInstance.GetStream())
using (var file = File.Create("test.bin"))
{
    stream.CopyTo(file);
}
//lesen
using (var file2 = File.OpenRead("test.bin"))
{
    myOtherClassInstance = MyClass.Create(file2);
    Console.WriteLine(person2);
}

LaTino

"Furlow, is it always about money?"
"Is there anything else? I mean, how much sex can you have?"
"Don't know. I haven't maxed out yet."
(Furlow & Crichton, Farscape)

W
872 Beiträge seit 2005
vor 7 Jahren

Das Schreiben auf den Streams macht Sinn bei Files.
Hier geht es um Network-Streams - da würde ich immer mit byte-Arrays arbeiten, insbesondere wenn man mehr macht, arbeitet man dann schnell mit mehreren Threads und dann sollte man die Klassen sowenig koppeln wie nötig.