Hallo boonkerz,
ich habe die kleinen Problemchen im Code behoben und die Änderungen bei Codeplex eingecheckt. Hier kannst Du die erste mono-taugliche Version abrufen: http://zyan.codeplex.com/SourceControl/changeset/changes/4988
Den mono-Test habe ich mit mono 2.8 unter Windows durchgeführt. Ein Test unter Linux steht noch aus (Das aktuelle VMWare Image wird gerade heruntergeladen und ist leider erst in ein paar Stunden fertig 😉)
Aber unter Windows schnurrt Zyan schon auf der mono Laufzeitumgebung, was folgender Screenshot zeigt:
Hallo,
ich möchte für mein quelloffenes Projekt Zyan gerne automatische Tests erstellen, um die Qualität zu erhöhen.
Es handelt sich dabei um ein Framework für verteilte komponentenbasierte Anwendungen.
Wie testet man sowas am besten? Ich müsste für einige Tests ja einen Server und einen Client starten, die übers Netzwerk miteinander kommunizieren.
Hat jemand von euch schon mal Tests für etwas ähnliches geschrieben?
Hallo boonkerz,
ich habe Zyan eben mit dem Mono Migration Analyzer (MoMa) analysieren lassen. Du findest das den MoMa-Prüfbericht unten im Anhang als PDF.
Es sind nur ein paar Kleinigkeiten.
Die CustomErrors-Eigenschaft ist in Mono wohl(noch) nicht implementiert. Die braucht man aber nicht zwingen, damit Zyan läuft. Über CustomErrors wird eingestellt, ob Exceptions vom Server serialisiert und zum Client übertragen werden sollen, oder nicht.
Dann wird an zwei Stellen ein Typvergleich gemacht, der nicht ganz mono konform ist. Sollte auch kein Problem sein, das anzupassen.
Zu guter letzt hat MoMa noch zwei P/Invokes gefunden. Die werden beide vom Zyan.Communication.Security.BasicWindowsAuthProvider abgesetzt. Dieser Authentifizierungsprovider ist optional und speziell für die Prüdung von Windows-Benutzern entwickelt. Da ich diese P/Invokes nicht sinnvoll ersetzen kann, wird der BasicWindowsAuthProvider unter mono nicht funktionieren. Vermutlich würde ihn aber auch kein mono-Entwickler vermissen, da er vom Zweck her schon Windows bezogen ist.
Es sind also keine unlösbaren Probleme. Ich werde den Zyan-Code entsprechend anpassen und einen Test mit mono machen.
Ich versuche es so hinzukriegen, dass MS.NET und mono mit der selben Assembly arbeiten können. Das sollte doch wie folgt funktionen, oder?
public static class MonoCheck
{
public static bool IsRunningOnMono()
{
return Type.GetType ("Mono.Runtime") != null;
}
}
...
if (MonoCheck.IsRunningOnMono())
Console.WriteLine("Mono Implementierung");
else
Console.WriteLine("Microsoft.NET Implementierung");
Neuigkeiten zur mono-Unterstützung von Zyan, werde ich hier posten.
... wieso nutzt du nicht eine externe Komponente, bzw. nimmst den "ComponentContainer" raus, in eine eigene Klasse?
Ich hab Deinen Vorschlag aufgegriffen und die Komponentenverwaltung nun als separate Klasse rausgezogen. Das ganze nennt sich jetzt Komponenten-Katalog (ComponentCatalog) und kann auch ganz ohne Verteilung genutzt werden.
Der Ansatz hat sich als sehr vorteilhaft erweisen, da ich so ganz leicht einen Komponenten-Katalog in verschiedenen ZyanComponentHosts mit verschiedenen Protokollen hosten kann.
Neu ist in der Version 0.8 auch die Unterstützung von zusammensteckbaren Anwendungen im neuen Namensraum Zyan.Communication.Modularity. Die Klasse ZyanApplication fungiert dabei als Stammobjekt und Microkernel. Sie lädt sog. Module (Gruppierung von Assemblies in einem Unterverzeichnis, welches den Modulnamen darstellt). Module, die sich kennen (also über eine gemeinsame Shared-Assembly verfügen) können über die API miteinander kommunizieren.
edit 19.12.2010: Modularitiy habe ich in Version 1.0 wieder rausgenommen. Das ist ein eigenes großes Thema und hat nichts direkt mir Kommunikation zu tun. Ich werde das Thema in einem anderen Open Source Projekt adressieren.
Das ist alles natürlich noch sehr ausbaufähig.
Antwort ist zu finden unter: Rainbirds Zyan: Mehere Objekte publishen
Hallo Tarion,
wie gfoidl bereits angemerkt hat, könnte Zyan für Dich interesant sein.
Daher suche ich aktuell eine alternative, zuverlässige Bibliothek, welche:
- eventbasiert arbeitet
Zyan wurde für die verteilung von Event Based Components entworfen. Ereignisgesteuerte Szenarien lassen sich deshalb gut abbilden.
"eventbasiert" ist allerdings auch sehr allgemein formuliert. Was verstehst Du denn genau darunter?
- Clients verwaltet
Zyan hat eine eigene Sitzungsverwaltung, die man auch sehr leicht durch eine eigene Variante austauschen kann. Generell werden Sitzungen in Zyan vom Client aus gestartet. Der Client erzeugt dazu eine eindeutige Sitzungskennung und gibt diese dem Server bei der Anmeldung mit. Der Server merkt sich diese Kennung und assoziiert alle folgenden Aufrufe mit dieser Sitzung. Natürlich funktioniert das alles automatisch unter der Haube.
- Mit unerwarteten Verbindungsabbrüchen gut umgeht
Standardmäßig verwendet Zyan Socket-Caching. Das heißt Sockets werden eine bestimmte Zeit offen gehalten, um die Kosten der Socketerzeugung beim nächsten Aufruf zu sparen.
Das lässt sich durch eine kleine Änderung im Zyan-Quellcode aber ausschalten. Man muss lediglich folgende Zeile der CreateChannel-Methode der verwendeten ProtocolSetup-Klassen wie folgt ändern:
// Standardwert im Code
channelSettings["socketCachePolicy"] = SocketCachePolicy.Default;
// Änderung: Socket-Caching abschalten
channelSettings["socketCachePolicy"] = SocketCachePolicy.AbsoluteTimeout;
Ich werde das aber eh als Einstellung über die API von aussen einstellbar machen, da das Socket-Caching Probleme beim Einsatz in einem NLB-Cluster macht.
Wenn das Socket-Caching ausgeschaltet ist, wird für jeden Aufruf ein neuer Socket geöffnet. Du kannst dann zwischen den einzelnen Aufrufen z.B. den Netzwerkstecker rausziehen, ohne dass die Anwendung beim nächsten Aufruf Probleme hätte (natürlich nur, wenn der Stecker bin dahin wieder drin steckt). Wenn die Verbindung während eines Aufrufs abbricht, dann wird eine SocketException bzw. eine RemotingException (je nach dem, wie weit die Verarbeitung fortgeschritten ist) geworfen, die Du bequem am Client fangen und dann entscheiden kannst, wie sich der Client bei einem Abbruch verhalten soll.
Verbindungsabbrüche sollten also kein Problem für Zyan sein.
- Wenn möglich diagnostic Möglichkeiten hat
Ist noch nicht drin, kommt aber noch rein (ist ja auch noch Version 0.7 😉).
Zyan basiert auf Remoting. Ich werde die Diagonistic-Möglichkeiten von Remoting in die API einarbeiten und erweitern. Ein Logging, wann was von wem aufgerufen wurde, und wie lange die Verarbeitung gedauert hat, bzw. welche Fehler dabei aufgetreten sind, soll den Weg ins Zyan-API finden.
Hallo serial,
in beiden Stellen muss abgesichert werden. Wenn ich nur die BLL-Funktionen absichere, dann merkt der Benutzer erst dann, dass er nicht berechtigt ist, wenn er schon auf den Button gedrückt hat. Er soll den Button aber eigentlich gar nicht erst sehen.
Ideal finde ich deshalb ein System, welches BLL-Funktionen und Oberflächenelemente gleichermaßen absichert. Und das mit einer gemeinsamen Datenbasis. Wenn ein bestimmter Knopf eine bestimmte BLL-Funktion aufruft, dann kann ich dem Knopf ja den selben Rechteschlüssel zuordnen, wie der Funktion.
So eine "Funktionsbasierte Rechteprüfung" haben die meisten Anwendungen. Was oft fehlt, ist eine "Datenbezogene Rechteprüfung". Eine die z.B. die Frage beantworten kann, ob Benutzer Mustermann Datensatz 4711 sehen darf, oder nicht.
Berechtigungen sollten immer irgendwo außerhalb des Codes gespeichert werden (z.B. in einer Datenbank).
Was auch immer ich damit meine. Der FLOAT Wert "Weight" muss überall einprogrammiert werden.
Ich glaube ich verstehe, wo der Schuh drückt. Du möchtest flexible Datenstrukturen, die komfortabel, schnell und leichtgewichtig sind. Vor allem möchtest Du keine Klassen starr hinschreiben.
Das .NET Framework hat eine solche Struktur seit Version 1.0: Das DataSet. DataSets bzw. DataTables sind sehr flexibel. Trotzdem bieten sie jede Menge Komfort (z.B. Linq2DataSet) und können schnell zugregriffen werden (Schlüsselspalten werden automatisch idiziert). Serialisierung ist auch auch kein Thema. Egal ob binär oder XML.
Vergiss den starren ORM-Käse und schau Dir mal das DataSet bzw. die DataTable (beide im Namensraum System.Data) an.
Ob Du dann noch eine Embedded DB dahinter hast oder nicht, ist dem DataSet egal. Du kannst es auch ohen weiteres als Mini-DB einsetzen. Allerdings nur, wenn Du nicht mehr Daten verarbeiten willst, als in Deinen Hauptspeicher passen. Falls das nicht zutrifft, solltest Du wirklich eine Embedded DB dahinter hängen.
Vergiss Access-MDBs. Das ist doch Schrott. Ehrlich. Access als Front-End ist in bestimmten Szenarien eine feine Sache, aber niemals als Datenbanksystem!
ABER: Der Windows Explorer basiert derzeit nicht auf .NET 4.0, und obige Aussage gilt NUR für in .NET 4.0 kompilierte Anwendungen. Das heißt, sobald es eine Version vom Windows Explorer gibt, die .NET 4.0 unterstützt, kann man Shell Extensions problemlos in .NET schreiben.
Ähm, ist der Windows Explorer nicht in C++ geschrieben?
Soweit ich weiß ist der Windows Explorer keine verwaltete Anwendung.
Das heißt, er unterstützt keine .NET Version mehr als eine andere.
Oder habe ich da was verpasst?
Hallo caldicot,
es sollte schon so funktionieren, wie Du es beschreiben hast.
Du kannst mit einem Host beliebig viele Komponenten hosten. Clientseitig brauchst Du auch nur eine Connection. Diese eine Connection kann Proxies für den Zugriff auf verschiedene Komponenten erzeugen.
Ich habe Dir kurz ein Beispiel geschrieben, welches bei mir auf Anhieb funktioniert hat (Siehe Anhang).
Sollte es bei Dir nicht funktionieren, dann poste bitte die genaue Fehlermeldung oder beschreibe das unerwartete Verhalten.
Schön dass Dir Zyan grundsätzlich gefällt.
Hallo caldicot,
ich habe eine Version des Remoting-Helfers mit .NET 4.0 erstellt. Bei mir konnte ich keine Probleme feststellen.
Eingesetztes Betreibssystem: Windows Vista Ultimate 64-Bit
Ist zwar kein Windows 7, aber das sollte sich bei Sockets nicht anders verhalten.
Bitte schau mal, ob meine .NET 4.0 Version bei Dir läuft.
P.S.: Zyan ist genauso einfach einzusetzen, wie der Remoting-Helfer.
Hallo caldicot,
mein Projekt läuft auf dem selben PC ohne Probleme? Das ist seltsam.
Wird die Ausnahme vom Client oder vom Server geworfen?
Hast Du mal versucht, einen anderen Port zu verwenden?
Welche Berechtigungen haben die Benutzer, unter denen die beiden Prozesse laufen?
Ganz nebenbei: Für größere Projekte ist der Remoting-Helfer ein bischen unterdimensioniert. Hier findest Du ganz aktuell den großen Bruder: http://zyan.codeplex.com/
Hallo Gentleman2006,
alternativ könntest Du auch das Microsoft ScriptControl einsetzen. Das ist ein ActiveX-Steuerelement, welches die dynamische Ausführung von VBScript ermöglicht. Vorteil dabei ist, dass der VBScript-Code direkt mit Objekten deiner .NET Applikation kommunizieren kann.
Jedenfalls tauchen auf diesem Notebook erhebliche Probleme auf, die auf allen anderen Rechnern im Büro kein Thema sind.
...
Was soll ich tun? Das Notebook neu aufsetzen?
Wenn Du das Problem wirklich nur mit diesem einen Gerät hast, würde ich das neu aufsetzen. Es könnte Wochen dauern, den Fehler in der Windows-Installation zu finden. Da ist Neuaufsetzen vom Zeitfaktor her vermutlich günstiger.
Hallo s0h0,
Du verschenkst mit dem DataAdapter+Mapping Ansatz einen Haufen Performance! Statt eines DataAdapters solltest Du DataReader zum lesen und direkte Commands zum speichern verwenden.
Du lässt Dir vom Adapter eine DataTable erzeugen, nur um daraus eine Liste mit eigenen Objekten zu erzeugen. Es ist wesentlich schneller Deine Objekte direkt aus den Daten eines DataReaders zu erzeugen. Hier ein Beispiel, wie der DataReader eingesetzt wird (allerdings ohne WCF): How to Fill a DataGrid in Silverlight 4 with SQL DataReader
Es ist Schade, dass SL4 keine DataSets unterstützt, aber daran kann man nichts ändern.
Hallo malignate,
Irgendwie sieht das wie eine Neuentwicklung von WCF aus, zumindest teilsweise.
Keineswegs. Es ist vielmehr eine Erweiterung von .NET Remoting.
Ich hatte anfangs gründlich überlegt, ob ich WCF oder .NET Remoting als Basis verwenden soll und habe mich für letztes entschieden.
WCF zwingt einem ein serviceorientiertes Programmiermodell auf. Das ist toll in einem plattformübergreifenden Szenaraio, aber wirft einem für reine .NET zu .NET Kommunikation nur Steine in den Weg. Um meine Entscheidung besser zu verstehen, hier eine Liste der Contra-WCF-Argumente:*Bei WCF gibt es keinen Aufrufkontext (CallContext) der implizit Daten über eine Aufrufkette von mehreren Services transportiert. *Das Erweiterungsmodell von WCF ist wesentlich komplexer als das von .NET Remoting. *WCF unterstützt nicht die schnelle binäre Serialisierung von ADO.NET DataSets (RemotingFormat=Binary; Das hat nicht unbedingt was mit EBCs zu tun, aber ich bin ein großer Anhänger von DataSets und da gefällt es mir natürlich nicht, dass WCF diese nicht optimal unterstützt). *Mit WCF kann man keine Objektreferenzen versenden. *WCF ist zu starr, da man alles (z.B. Callbacks, Faults) explizit über Kontrakte definieren muss. *WCF ist ein Konfigurationsmonster! *WCF unterstützt den BinaryFormatter nicht. *Bei WCF ziehen sich Attribute wie bei einem durchwachsenen Schinken durch den Code. Ich mochte durchwachsenen Schinken noch nie.
Die durchwachsene Schinken-Geschichte führt in der Praxis dazu, dass man den WCF-Service als Fassade für die eigentliche Geschäftkomponente dahinter verwendet. Das bedeutet dann stumpfsinnig Methodenaufrufe über die Service-Fassade meistens 1:1 durchzureichen. Das macht keinen Spaß.
In besonderem Maße ausschlaggebend war die Tatsache, dass es bei WCF keinen Aufrufkontext gibt. Es gibt nur den OperationContext, der aber nur einen Aufruf weit funktioniert. Wenn ich Aufrufketten habe, wie Client -> Service A -> Service B, dann stehe ich mit WCF im Regen.
Warum nicht einfach ein Wrapper über WCF als Schnittstelle zu EBCs und Vereinfachung der Kommunikation?
Das ist eine berechtigte Frage.
Mit WCF einfach ein EBC-Zwischenstück zu bauen, welches die Nachricht vom Ausgangspin aufnimmt und diese zum Eingangspin der entfernten Komponente transportiert, klingt zunächst naheliegend. Ralf hat das so ähnlich in seinem Beispiel mit Application Spaces (Remote Communication mit Event-Based Components und Application Space) aufgebaut. Der Aufbau lässt sich so darstellen:
A<->P...S<->B
A=Komponente A (Geschäftskomponente)
B=Komponente B (Geschäftskomponente)
P=Proxy (Infrastrukturkomponente)
S=Stub (Infrastrukturkomponente)
<-≥Verdrahtung
...=Netzwerkübertragung
Damit Komponente A die entfernte Komponente B konsumieren kann, müssen ihre Pins mit einem Proxy verdrahtet werden. Die Pins von Komponente B müssen auf der Serverseite mit einem Stub verdrahtet werden, damit Nachrichten zwischen den beiden fließen können.
Dauraus ergibt sich eine Verdoppelung der zu ziehenden Drähte! Und das bei jeder entfernten Komponente: Immer und immer wieder.
Okay, stumpfsinnige Verdrahtung ist ein Grundproblem von EBCs, war irgendwann durch einen schicken Designer eingedämmt werden soll. Da will ich nicht schon wieder drauf rumreiten.
Viel schlimmer als der erhöhte Verdrahtungsaufwand ist aber die Tatsache, dass ich die Infrastruktur-Zwischenstgücke das Modell verkomplizieren. Ich muss sie mir immer wegdenken, wenn ich meine Geschäftskomponenten zusammenstecke. Da helfen mir auch keine Boards, da ein Boards nicht in zwei Prozessen leben kann.
Ich will nicht A<->P...S<->B denken müssen, sondern ich will eigentlich A<->B denken. Wenn ich verteilte Geschäftskomponenten zusammenstecke, dann möchte ich auf der Abstraktionsebene dieser Geschäftskomponenten verharren. Infrastrukturkomponenten stören dabei. Deshalb müssen sie transparent gemacht werden. Darum kümmert sich Zyan.
Mit Zyan kann ich A<->B denken. Zwar wird im Clientprozess für B auch ein Proxy verwendet, aber der fühlt sich genauso an wie B und muss leider sein, da B nunmal in einem anderen Prozess lebt. Ich verdrahte A mit dem Proxy von B und diese Verdrahtung wird von Zyan autonatisch auf die echte Komponente B angewendet. Also keine verdoppelten Drähte und keine Infrastruktur-Fremdkörper im Modell.
Ich möchte EBCs gerne in der Praxis einsetzen. Damit das funktionieren kann, müssen EBCs einfach und intuitiv einsetzbar sein. Zumindest in verteilten Szenarien sind EBCs mit .NET-Bordmitteln das definitiv nicht. Mit Zyan wird die Verteilung von EBCs dagegen kinderleicht und geht vor allem von Statten, ohne dass man viel Code hinschreiben muss. Zyan selber ist nicht aus EBCs gebaut, aber das .NET Framework und z.B. WCF ja auch nicht 😉.
Selbst wenn sich bei meinen Praxistests herausstellt, dass EBCs nicht alltagstauglich sind, war die Mühe Zyan zu schreiben nicht vergebens, denn Zyan kann auch mit ganz klassischen Nicht-EBC-Komponenten ungehen. Dann ist es immer noch einfacher und intuitiver als WCF.
Hallo Peter Bucher,
Was mir aber ein wenig missfällt, sind die Kommentare - der Noise - zwischen dem Code, sowie der Gebrauch von Region und folgend, die langen Klassen, die da teilweise vorkommen.
Die Kommentare und Regions sind so gewollt. Ich habe Code-Kommentare in deutschem Klartext sehr schätzen gelernt. Regions finde ich auch sehr praktisch. Aber das ist alles Geschmacksache.
Mit den langen Klassen hast Du allerdings völlig Recht. Die müssen noch Refaktorisiert werden. Vieles ist relativ schnell runtergeschrieben. Ich wollte die Grundfunktionen erstmal am Laufen haben, damit ich den Code veröffentlichen kann. Der Feinschliff kommt dann so nach und nach. Ich bin aber für solche Anregungen sehr dankbar. Das hilft mir, meine Codequalität in diesem Projekt zu steigern.
Beispielsweise hast du im ZyanComponentHost in einer Region mit 3, 4 Methoden einen sehr rudimentären "DI-Container" drin, bzw. das Grundstück davon mit Registrierung, Deregistrierung sowie der Ausgabe aller Registrierungen und natürlich das erstellen einer Instanz.
Drin ist auch Singleton. Soweit ich gesehen habe.
Das wird noch entzerrt und soll auch in separate Klassen aufgeteilt werden. Wie gesagt, ich habe zuerst mal alles in den zentralen Kern reingestopft um auch zu testen, ob das alles so funktioniert. Zuerst wird die Sitzungsverwaltung ausgelagert werden, da diese auch noch Schnittstellen für Erweiterungen spendiert bekommt. Momentan sind nur In-Memory-Sessions möglich, was eine große Einschränkung für die Skalierbarkeit ist. Das wird sich ändern. In diesem Zuge wird auch die Sitzungsverwaltung aus dem Kern ausgelagert.
... wieso nutzt du nicht eine externe Komponente, bzw. nimmst den "ComponentContainer" raus, in eine eigene Klasse?
Es muss einfach sein. Und zwar in Anwendung, Konfiguration und Deployment. Eiserne Regel für das Zyan-Framwork an sich: Eine einzige DLL!
Ich will noch einen Zyan.Server (EXE) schreiben, der als generischer Host-Prozess verwendet werden kann und Dinge wie Deployment und Monitoring adressiert.
Aber wer möchte, kann ohne Änderungen am Code externe DI-Systeme wie Unity zusammen mit Zyan verwenden. Dafür hat der ZyanComponentHost folgende Methode:
/// <summary>
/// Registriert eine bestimmte Komponente.
/// </summary>
/// <typeparam name="I">Schnittstellentyp der Komponente</typeparam>
/// <param name="factoryMethod">Delegat auf Fabrikmethode, die sich um die Erzeugung und Inizialisierung der Komponente kümmert</param>
void RegisterComponent<I>(Func<object> factoryMethod);
Du kannst also einfach eine Factory-Methode übergeben, und so das Erstellen der Komponente in eigenen Code auslagern. Auf welche Art und Weise Du dann die Komponenteninstanz erzeugst, ist Dir überlassen.
Ich will auch bei Zeiten noch ein Beispiel schreiben, wie man sowas mit Unity machen kann.
Das ist es mir momentan auch noch.
Es ist momentan noch sehr viel Bewegung im ganzen EBC-Konzept. Das macht es schwierig, den Überblick zu behalten. Auch die Tatsache, dass dauernd neue Entwurfsaspekte, Pattern und Varianten hinzukommen, kann etwas verwirrend sein.
Ich habe noch keinen wirklichen konzeptionellen Unterschied (außer durch die Verwendung anderer technischer Mittel zur Implementierung also: .Net, Delegates, Events etc.) z.B. zu LabVIEW, einigen ausgefeilten Workflow-Engines etc. entdecken können
Verringerung von Abhängigkeiten zwischen Komponenten durch den Einsatz von Delegaten und ausgelagerter Verdrahtung. Das würde ich als den Kern des Konzepts bezeichnen. Simpel aber genial.
Eines meiner großen ? ist es eben auf welchem Abstraktionsniveau ich EBCs einsetzen sollte.
Mir geht es genauso.
Der Übergang zwischen Komponenten und Services (brauche ich einen Service auf einer höheren Ebene öfter so wird er dort zur Komponente) ist doch ohnehin fließend je nach dem auf welche Abstraktionsebene man geht.
Service und Komponente ist in meinen Augen dasselbe. Ein Stück Software mit einer klar definierten Schnittstelle, welche so autonom wie möglich ist.
Die Frage lautet meinerseits also: Welche Arten von Komponenten/Tätern soll ich bauen?
... soll ich eine Komponente mit den Eingangspins "Wert1", "Wert2", "Wert3", ..., "Rechenart" und dem Ausgang "Ergebnis" bauen ...
Würde ich eher nicht tun. Zu filigran, zu fitzelig. Da schreibst Du am Ende mehr Verdrahtungscode, als Geschäftslogik.
... oder sollte ich mich eher auf dem Level von "Kunde" -> "Kreditantrag" -> "Genehmigung einholen" -> "Kredit vergeben/Kredit ablehnen" bewegen?
Das hört sich - finde ich - viel besser an. Anforderungen lassen sich aber nicht unbedingt immer gleichmäßig in Codekonstrukte umsetzen. Ganz interessant ist in dem Zusammenhang folgender Blog-Beitrag: Das Domänobjektmodell anders gedacht [OOP 2010]
Es gibt allerdings gar nicht immer eine GUI!
Das Interface der Komponente ist eine verbindliche Schnittstelle (Interface) zum Rest der Software. Die Schnittstelle kann daher mit einem Vertrag zwischen der Komponente und dem Rest der Software verglichen werden.
EBCs hängen nur über ihre Pins zusammen. Was eine Schnittstelle für eine Klasse ist, das ist ein Delegat für eine Methode. Man hat also viele kleine Verträge, statt eines großen Vertrages. Auf Schnittstellen könnte man deshalb sogar komplett verzichten. Das Problem sind vielmehr die Nachrichtentypen, welche trotz ausgelagerter Verdrahtung gemeinsam genutzt werden. Dafür gibt es keine Lösung! Kommunikationspartner müssen die gleiche Sprache bzw. das gleiche Protokoll sprechen. Natürlich könnte man z.B. mit untypisierten DataTables arbeiten, aber da müssen die Komponenten auch die Spalten kennen bzw. richtig interpretieren.
Eine etwas größere Beispielanwendung wie z.B. die von Rainbirds
> wäre schön damit man besser erkennen kann wo und wann EBCs eingesetzt werden. Eine solche Anwendung rein mit EBCs implementiert kann ich mir nämlich nicht vorstellen.
Ich bin dabei, sowas zu erstellen. Es soll eine kleine verteilte Mini CRM-Anwendung werden, die aus verteilten EBCs mit Zyan aufgebaut wird. 8)
Das wird auch für mich der ultimative EBC-Praxistest.
Hallo Sebastian.Lange,
Für nicht EBC Kundige macht das auch mit der Doku natürlich alles keinen Sinn.
Ich bin mit der Zyan-Doku leider noch nicht bei EBCs angekommen. Ich wollte zuerst drin haben, wie man ein verteiltes Hello World mit Zyan zum laufen bringt und wie es grundlegend funktioniert. Ist ja aber auch noch nicht fertig. Ich werde noch ganz ausführlich erklären, wie man verteilte EBC-Style-Anwendungen mit Zyan erstellt.
Die kleine beiliegende Beispiel-Projektmappe ist nur ein mini, mini Demo um das aller grundlegendste zu zeigen.
Vielleicht kann Zyan hier noch etwas Begeisterungsarbeit leisten. 😃
Das hoffe ich. Es ist allerdings auch ein Test für die Praxistauglichkeit. Ich habe vor ein kleines Mini-CRM-System-Beispielprojekt mit EBCs und Zyan aufzusetzen, um auszuloten, ob EBCs für die erstellung von Buisness-Anwendungen wirklich Vorteile bringen. Alles was es im Netz momentan gibt, geht nicht wirklich über Hello World hinaus. Es muss eine Anwendung her, die zumindest halbwegs Real World-Charakter hat. Zuerst musste die Verteilung von EBCs aber erst mal laufen. Das ist mit der aktuellen Zyan-Version nun geschafft.
Zyan geht bei der Verteilung übrigens einen anderen Weg, als der von Ralf Westphal in seinem Beispiel unter Remote Communication mit Event-Based Components und Application Space Vorgeschlagene!
Aber selbst ganz ohne EBCs ist Zyan ein nützliches Kommunikations-Framework für einfache und intuitive .NET zu .NET Kommunikation.
Hallo zusammen,
ich habe kürzlich ein freies Kommunikations Framework auf Codeplex veröffentlicht, welches für die selbe Art von Anwendungen geeigent ist, wie der kleine Remoting Applikationsserver hier in diesem Thread.
Nähere Infos und den Download-Link gibt es unter Zyan - Framework für verteilte EBCs (unterstützt auch klassische Komponenten)
Zyan ist die Weiterentwicklung der ursprünglichen Applikationsserver-Idee.
Vielleicht ist das Projekt ja für den einen oder anderen von euch interessant.
Hallo zusammen,
angeregt durch die Diskussionen über Event Based Components habe ich ein Framework für verteilte Anwendungen geschrieben, welches auch EBCs unterstützt.
Mit Zyan können Komponenten auf verschiedenen Computern laufen und kommunizieren untereinander übers Netzwerk. Darüber hinaus bietet Zyan Zusatzdienste wie Verschlüsselung, Authentifizierung, Sitzungsverwaltung und automatische Übertragung von verteilten Transaktionen (via System.Transactions). Die Kommunikation kann wahlweise über TCP oder HTTP erfolgen. Sicherheitsfeatures etc. sind individuell einstellbar und können - bei Bedarf - auch leicht abgeschaltet werden. Zyan bietet Schnittstellen zur Erweiterung des Systems an (z.B. für benutzerdefinierte Authentifizierung oder eigene Netzwerkprotokolle).
Es werden natürlich auch klassische Komponenten unterstützt, die ++nicht ++nach EBC-Architektur entworfen wurden!
Ihr findet das Projekt zum runterladen, sowie den Quellcode und die Dokumentation (ist noch nicht vollständig, aber wächst fast täglich) unter http://zyan.codeplex.com/.
Es gibt auch eine kleine Beispielprojektmappe, die an einem sehr einfachen Beispiel zeigt, wie verteilte EBCs mit Zyan funktionieren. Hier geht´s direkt zum Download-Bereich: http://zyan.codeplex.com/releases
Das Projekt steht unter der MIT Lizenz und kann somit frei für eigene Zwecke verwendet werden. Jegliche Haftung ist allerdings ausgeschlossen!
Über Kommentare, konstruktive Kritik oder Verbesserungsvorschläge würde ich mich sehr freuen. Vorzugsweise direkt unter http://zyan.codeplex.com/discussions. Wer Bugs findet, kann Sie gerne im Issue Tracker unter http://zyan.codeplex.com/workitem/list/basic eintragen.
Hallo rock4k,
wie serial bereits angemerkt hat, sollte der TypeFilterLevel auf den BinaryFormatter und nicht auf den Channel direkt angewendet werden.
Wenn Du den Server wie folgt konfigurierst, sollte es auch ohne Domäne klappen:
// Konfiguration für den TCP-Kanal erstellen
System.Collections.IDictionary channelSettings = new System.Collections.Hashtable();
channelSettings["name"] = "MeinServer";
channelSettings["port"] = iPort;
channelSettings["secure"] = false;
// Binäre Serialisierung von komplexen Objekten aktivieren
BinaryServerFormatterSinkProvider serverFormatter = new BinaryServerFormatterSinkProvider();
serverFormatter.TypeFilterLevel = TypeFilterLevel.Full;
BinaryClientFormatterSinkProvider clientFormatter = new BinaryClientFormatterSinkProvider();
// Neuen TCP-Kanal erzeugen
TcpChannel channel = new TcpChannel(channelSettings, clientFormatter, serverFormatter);
// Sicherstellen, dass vollständige Ausnahmeinformationen übertragen werden
if (RemotingConfiguration.CustomErrorsMode != CustomErrorsModes.Off)
RemotingConfiguration.CustomErrorsMode = CustomErrorsModes.Off;
Hier noch das Gegenstück für den Client:
// Konfiguration für den TCP-Kanal erstellen
System.Collections.IDictionary channelSettings = new System.Collections.Hashtable();
channelSettings["name"] = "MeinClient";
channelSettings["port"] = 0;
channelSettings["secure"] = false;
// Binäre Serialisierung von komplexen Objekten aktivieren
BinaryServerFormatterSinkProvider serverFormatter = new BinaryServerFormatterSinkProvider();
serverFormatter.TypeFilterLevel = TypeFilterLevel.Full;
BinaryClientFormatterSinkProvider clientFormatter = new BinaryClientFormatterSinkProvider();
// Neuen TCP-Kanal erzeugen
TcpChannel channel = new TcpChannel(channelSettings, clientFormatter, serverFormatter);
// Sicherstellen, dass vollständige Ausnahmeinformationen übertragen werden
if (RemotingConfiguration.CustomErrorsMode != CustomErrorsModes.Off)
RemotingConfiguration.CustomErrorsMode = CustomErrorsModes.Off;
Großer Nachteil an der Sache ist, dass die Kommunikation so unverschlüsselt ist.
Wenn Du verschlüsselte Kommunikation ohne Domäne haben willst, kannst Du zukünftig Zyan einsetzen. Zyan verwendet - bei Bedarf - ein eigenes Sicherheitsprotokoll mit 3stufigem Handshake (TcpCustomServerProtocolSetup verwenden). Mit wenigen Handgriffen, kannst Du Zyan auch so konfigurieren, dass die Authentifizierung z.B. auf Basis einer Datenbankabfrage (SQL Server ö.ä.) durchgeführt wird.
Mit Zyan kannst Du auch Objekte für den Remotezugriff veröffentlichen, die nicht von MarshalByRefObj abgeleitet sind. Kannst Dir das Zyan-Projekt ja mal anschauen.
Hallo serial,
ich habe das Famework für verteilte EBCs auf CodePlex veröffentlicht. Du findest es unter: http://zyan.codeplex.com/
Selbstverständlich kann man damit auch ganz klassische verteilte Anwendungen, also ganz ohne EBC-Vorgehensweise erstellen. Ganz nach belieben.
Ich habe auch ein kleines Beispielprojekt hochgeladen. Ist nichts großartiges, reicht aber um zu zeigen, wie der verteilte EBC-Ansatz grundlegend funktioniert.
Für Anregungen, Fragen und Diskussionen bin ich jederzeit offen.
Achtung! Wegen möglichen Namenskonflikten mit einem kommerziellen Softwareprodukt, habe ich den Projektnamen von Cyan auf Zyan geändert.
Hallo serial,
ich bin gerade dabei ein Kommunikations-Framework für verteilte EBCs zu schreiben. Ich werde die erste Version in wenigen Tagen veröffentlichen.
Wenn Du willst, kann ich in diesem Thread hier auch einen Link (wird bei CodePlex veröffentlicht) dazu posten.
Sobald das Framework in den Grundzügen fertig ist, möchte ich auch eine etwas größere verteilte Beispielanwendung damit aufbauen um zu prüfen, ob EBCs in der Praxis für verteilte Geschäftsanwendungen zu gebrauchen sind, oder ob sich nur die Theorie gut anhört.
Wenn Du daran Interesse hast, halte ich Dich gerne auf dem Laufenden.
wäre somit für diesen Anwendungsfall WebDAV eine Alternative (so wie im Ursprungsthema angemerkt)?
WebDAV hätte ein ähnliches Problem wie die DB-Speicherung, da nicht alle Windows-Anwendungen WebDAV unterstützen.
In Sachen Metadaten und Berechtigungen wäre mit WebDAV nicht viel gewonnen.
WebDAV hätte allerdings den Vorteil, dass auch Zugriff übers Internet möglich werde (SSL vorausgesetzt).
Hallo herbivore,
Ich denke auch nicht, dass eine neue Diskussion für dich persönlich was bringt.
Wenn ich darüber nachdenke, hast Du damit nicht ganz unrecht.
Die Diskussion hat ihr mögliches geleistet, der Rest kann nur durch Ausprobieren in der Praxis geschafft werden. Bevor ich es nicht selber in einem abgesteckten Projekt ausprobiert habe, werde ich vermutlich immer daran herumnörgeln.
Also möchte ich gfoidls Schlußwort gerne so stehen lassen.
... einen dazu zwingen das so umsetzen. 😦
Diese Leute sind meinst empfänglich für betriebswirtschaftliche Argumente. Mit ein bischen Fingerspitzengefühl lässt sich das meistens geradebiegen.
Es ist meistens kontraproduktiv sich mit technischen Argumenten geradeheraus gegen Entscheidungsträger zu stellen. Besser ist es auch sie einzugehen und zu versuchen die Dinge aus ihrer Sicht zu sehen. Für schwachsinnige Entscheidungen gibt es meistens einen Grund, der aber nicht immer offen ausgesprochen wird. Als Entwickler sollte man sich auch etwas auf Diplomatie verstehen und auch mal als Manager denken können.
Hallo Tom2010,
oder Du setzt die NTFS-Rechte auf dem Server automatisiert für jede Datei durch einen Windows-Dienst, der auf dem File Server läuft. Du musst die Dateien dann aber irgendwie kategorisieren, damit Du weisst, welche Datei welche NTFS-Rechte bekommt.
Außerdem müsstest Du auch was einbauen, um die Rechte bereits abgelegter Dateien nachträglich für eine ganze Kategorie auf einmal ändern zu können.
Hallo Tom2010,
Woher weiss die Anwendung wann es soweit ist?
Du könntest z.B. einen FileSystemwatcher verwenden, um Dich per Ereignis informieren zu lassen, wenn Änderungen in die Datei geschrieben werden.
Vielleicht macht der Benutzer Excel aber auch einfach zu, ohne was zu speichern?
Du musst dann auch den Prozess überwachen, der die Datei geöffnet hat.
Für Office-Anwendungen kannst Du mit VSTO Add-Ins schreiben, die Dein Dateiablagesystem dort integrieren (Das beim speichern z.B. nicht der Standard-Dateidialog kommt, sondern ein Formular von Dir, welches dem Benutzer ermöglicht die Speicherung auf Deinem Server vorzunehmen und gff. noch Metadaten einzugeben). Wenn Du allerdings beliebige Dateien verwalten willst, musst Du das doch wieder von außen Steuern können, da nicht jede Anwendung das Schreiben von Add-Ins unterstützt.
Oder ist mein Ansatz generell falsch?
Falsch vielleicht nicht, aber er hat Nachteile:*Office-Dokumente können relative Verweise auf andere Office-Dokumente/Dateien haben. Wenn aber jede Datei einzeln aus der DB in Tempo geholt wird, werden diese Verweise nicht mehr funktionieren. *An die Dokumente kommt man nur noch über Deine Software ran. Das macht es für andere Anwendungen - die keine Plug-In-Unterstützung haben - unmöglich auf die Dokumente zuzugreifen. Das ist eine große Einschränkung und hemmt die einfache Einführung neuer Anwendungen in die EDV-Landschaft. *Das NTFS-Rechtesystem greift nicht mehr. Du musst also ein eigenes Rechtesystem auf Basis der DB aufsetzen. Viel Arbeit, die nicht unbedingt nötig ist.
Wenn Du Dir dieser Nachteile bewusst bist und es triftige Gründe gibt das so zu machen (z.B. wenn die Client übers Internet mit dem Dateiablageserver kommunizieren), ist es okay.
Alternativ könntest Du die Dateien mit einer herkömmlichen Windows-Netzwerkfreigabe zugänglich machen und Metadaten zu den Dateien separat in einer DB speichern. Dann bleiben die Dateien mit herkömmlichen Mittel zugreifbar.
Hallo Grotesk,
statt docx musst du ein docm erstellen. docm-Dateien sind Open XML Word-Dokumente mit eingebetteten VBA-Makros.
Hier kannst Du das alles nachlesen: http://msdn.microsoft.com/en-us/library/aa338205(office.12).aspx
Hallo zusammen,
mir scheint es so, als herrsche keine Einigkeit darüber, was unter dem Begriff TDD zu verstehen ist. Auch wie und was zu testen ist, scheint nicht klar auf der Hand zu liegen.
Was haben Entwurfsmuster für GUIs mit Software Tests zu tun? Ich kann da keine Verbindung erkennen. Oder fehlt mir da als Test-Neuling und Test-Kritiker einfach noch das entscheidende Mosaik-Steinchen?
Mir kommt das teilweise immer noch überbewertet vor. Einige hier stellen TDD über Alles (so ist das zumindest bei mir rübergekommen). So nach dem Motto: "Eine gute Architektur ergibt sich automatisch, wenn man TDD macht". Einige positive Nebeneffekte im Code durch TDD leuchten mir ja ein. Aber mit Architektur hat das nichts zu tun.
Ich würde gerne noch wissen, bei was für Arten von Projekten welcher Nutzen sich durch TDD ergeben hat?
Hat jemand von euch TDD z.B. in einem größeren plattformübergreifenden Projekt eingesetzt? Wie war da die Nutzen-Ausbeute?
Oder hat jemand ein größeres Migrationsprojekt (in Richtung .NET) mit älteren Sachen wie VB6-ActiveX-Controls, COM+, Excel-Makros, sonstigem Office-Krempel oder gar DDE-Kommunikation mit TDD abgewickelt? Ist TDD bei solchen Projekten überhaupt anwendbar? Und wenn ja, lohnt es sich auch bei solchen Projekten wirklich mit TDD zu arbeiten?
Wenn wir hier diskutieren, wie hoch der Nutzen beim Testen von Hello World-Beispielen (Kreisberechnung und so was) ist, dann ist das Kaffeesatzlesen. Wie läuft tatsächlich es in der Praxis?
Wie sieht es z.B. mit Gespeicherten Prozeduren auf dem SQL Server aus? Wie testet ihr die? Ich will jetzt nicht hören, dass man Gespeicherte Prozeduren einfach gar nicht einsetzt (Ich vermeide sie selbst, wenn irgend möglich, aber sie haben ihre Daseinsberechtigung und enthalten Geschäftslogik, die ja eigentlich getestet werden müsste).
Wenn die zu testende Software-Lösung z.B. ein Word-Vorlage mit lebenswictigen VBA-Makros enthält, wie testet Ihr sowas?
Oder eine Access-Datenbank die VBA-Code enthält? Da ist nix mit automatischen Builds, etc. Hilft die TDD-Lehre einem bei sowas weiter?
Oder gibt es vielleicht bestimmte Konstrukte innerhalb einer Software-Lösung, die man doch besser vom Testen ausklammert?
Hallo gfoidl,
oh, das wusste ich noch nicht. Feine Sache!
Danke für den Hinweis.
Also du meinst ich sollte auf der Service Seite die Daten nicht ueber das Entity Framework holen sondern ganz normal über SQLConnection? Und dem Client ein typisiertes DataSet uebertragen?
Ja, das meine ich.
Wenn Du nur im LAN kommunizierst und nicht interoperabel sein musst, dann würde ich Dir auch .NET Remoting statt WCF als Kommunikationsframework empfehlen. Grund für diese Empfehlung ist, dass WCF im Vergleich zu Remoting ein komplizierter Kram ist (dafür beitet WCF allerdings mehr Möglichkeiten; Aber brauchst Du die alle?). Hier ein einfaches Remoting-Beispiel für den Einstieg (ist nicht für große Enterprise-Applikation gedacht, zeigt aber wie einfach und effektiv Remoting ist): Remoting-Helfer
Aber WCF ist auch okay. Ist am Ende Geschmacksache.
Hast du noch andere Belege fuer deinen Artikel?
Schau Dir mal die Beispiele im Web zu Entity Framework mit WCF an. Du findest kein Beispiel, welches mehrere Änderungen für eine Geschäftstransaktion an einem Stück zurück zum Server überträgt (und wenn, dann ist es ein umständliches Gewurstel; Siehe weiter unten: Self Tracking Entities). Alle haben sie in ihren WCF-Services zum Speichern von Änderungen Methoden wie
public void CreateCustomer(Customer customer)
{ ... }
public void UpdateCustomer(Customer customer)
{ ... }
public void DeleteCustomer(Customercustomer)
{ ... }
Das ist in meinen Augen "Hello World". Schon wenn ich drei Angebotspositionen in einem DataGrid speichern will, bin ich mit dem Ansatz am Ende. Daran, für jede Position UpdateSalesOfferItem aufzurufen und jedes Mal Netzwerkoverhead, Aufwand für Authentifizierung und Erstellen der Dienstinstanz in Kauf zu nehmen, will ich erst gar nicht denken. Vom Transaktionshandling will ich gar nicht anfangen.
Beispiel: Entity Framework in geschichteten Architekturen
Microsoft liefert mit .NET 4.0 eine Erweiterung Namens Self Tracking Entities aus. Damit wird bei den EF-Entities der RowState nachgerüstet. Wenn man aber sieht, wie viel Code der Code-Generator dafür erzeugt, dann kann von "schlanken" Objekten nicht mehr die Rede sein.
Das "fette" von den DataSets (was aber kein überschüssiges Fett ist) wird nun durchs Hintertürchen ins EF hineingetragen. Die selben Leute, die DataSets verdammt haben, weil sie ihnen zu "fett" waren, kommen plötzlich ins Schwärmen und lobpreisen die "neuen" Möglichkeiten des EF.
Hier findest Du Infos zu Self Tracking Entities: Working with Self-Tracking Entities
Ganz so toll ist das EF aber scheinbar doch nicht. Würde sich sonst Jörg Neumann von thinktecture die Mühe machen, ein ganz eigenes Persistenzframework zu schaffen, welches für verteilte Szenarien ausgelegt ist (Siehe CodePlex: Thinktecture.DataObjectModel)? Wohl kaum.
Allerdings frage ich mich, warum es denn unbedingt auf biegen und brechen was mit herkömmlichen Objekten sein muss, wenn es seit .NET 1.0 bereits eine exzellente Persistenzlösung gibt? Ich denke inzwischen, dass das ein "Modetrend" ist. In seinem Artikel in der DOTNETPRO (Ausgabe 04/2010) zur obigen Persistenzlösung schreibt er
In der Vergangenheit war hier in der Regel das DataSet der kleinste gemeinsame Nenner. Doch in Zeiten von WCF und O/R-Mapping ist dessen Verwendung nicht mehr sinnvoll; in Silverlight ist diese Klasse nicht einmal mehr enthalten. Warum der Einsatz nicht mehr sinnvoll sein soll, schreibt er allerdings nicht. Dass die Klasse nicht in Silverlight enthalten ist, hat nichts zu sagen. Im Compact Framework sind auch nicht alle Klassen vorhanden. Silverlight enthält auch viele andere Klassen nicht, die er vermutlich auch verwendet, wenn er gerade nicht Silverlight programmiert.
Ähnliche Aussagen über DataSets findet man leider überall im Web. Es hält sich auch immernoch bei einigen das Gerücht, dass DataSets intern mit XML arbeiten würden und deshalb langsam sein. Phantasie mit Schneegestöber. DataSets haben eine gute XML-Unterstützung, was aber nicht automatisch heißt, dass intern mit XML-DOM o.ä. gearbeitet wird.
Denn wir stehen hier vor einer Design Entscheidung...
Dann solltest Du Dir die Mühe machen und mit beiden Technologieen eine kleine Beispielanwendung schreiben.
Es gibt noch ein paar generell Punkte, die eine Entscheidung für oder gegen DataSets beeinflussen:
Wenn verschiedene RDBMS (z.B. SQL Server, Oracle, MySQL) unterstützt werden müssen, hat EF mit seiner Abstraktionsschicht einen großen Vorteil. Man programmiert nur noch gegen das Modell und der jeweilige EF-Provider erzeugt automatisch zur Laufzeit SQL. Je nach Qualität des EF-Providers und nach Komplexität der Aufgabenstellung, kommt man damit auch schon mal an die Grenzen. Auch mit dem EF bleibt ein Wechsel des RDBMS ganz ohne Änderungen am Code eine Utopie. Trotzdem vereinfacht die Abstraktion das Ganze erheblich. Aber sie kostet dafür auch Ressourcen.
Als Argument gegen DataSets wird noch oft angeführt, dass sie wegen der Affinität zum .NET Typsystem in heterogenen Umgebungen (z.B. in Verbindung mit Java) problematisch sind. Das wird in real-word Projekten aber vermutlich selten zum tragen kommen, da man eh nicht alle Aspekte der heterogenen Umgebung in seine Anwendung (oder sein Modul) hineintragen will. Integrationsschichten, Adapter (oder wie man es sonst noch nennt) sorgen da für die Umsetzung in neutrale Datenformate für die Kommunikation.
Ich habe auch schon gehört, DataSets seien obsolet, deprecated oder sonst irgendwie "veraltet". Das ist Quatsch mit Soße. DataSets sind fester Bestandteil von ADO.NET. DataSets kommen auch in Verbindung mit ganz aktuellen Technologieen wie z.B. Visual Studio Tools for Office zum Einsatz. Wer gerne LINQ einsetzt, kann dies dank Linq2DataSet auch mit DataSets tun: MSDN: Linq2DataSet Samples
Hier die Microsoft Roadmap für Datenzugriffstechnologieen (Stand Dez. 2009): MSDN: Data Access Technology Roadmap
DataSets und ADO.NET stehen nicht auf der deprecated/obsolete Liste. 😁
DataSets sind sehr flexibel. Auch an typisierte DataSets kann man zur Laufzeit ganz leich neue Spalten zufügen. Bei EF ist alles hartcodiert und in Stein gegossen.
Typisierte DataSets fühlen sich nicht "klassisch objektorientiert" an. Die erzegten Klassen heißen z.B. CrmDataSet, CrmDataSet.CustomerDataTable und CrmDataSet.CustomerDataRow. Diese Namenskonventionen mögen manche Leute nicht. Das ist aber kein DataSet-Problem, sondern eine Problematik von Code-Generatoren allgemein.
Wir lesen zu 85% die Daten nur aus der Rest ist Daten Manipulation. Es geht aber um sehr große Datenmengen, überwiegt dann vielleicht doch wieder der Vorteil der schlankeren Objekte?
In Sachen Geschwindigkeit schlägt klassisches ADO.NET mit DataAdapter und DataTable/DataSet das EF um ein Vielfaches. Schau Dir mal die folgende Grafik an: Entity Framework and LINQ to SQL Performance
Die Abstraktionsschicht des EF wird zu einem hohen Preis erkauft.
Für große Datenmengen ist das fast schon ein KO Kriterium.
Was die Serialisierung und Übertragung übers Netzwerk angeht, sind DataSets nicht größer, als andere Objekte auch (DataSets sind auch nur Objekte). Es werden ja nur die Daten serialisiert. DataSets speichern noch den OriginalValue, aber das müssen Self Tracking Entities auch tun.
Ich hoffe meine Informationen helfen Dir weiter.
WCF finde ich zumindest angenehmer zu nutzen, wobei ich dazu sagen muss, dass ich es noch nie in einem Projekt gebraucht habe ...
Remoting lässt sich sehr einfach einsetzen. Man muss nicht, wie bei WCF an den richtigen Stellen die richtigen Attribute setzen. Auch mit Vererbung gibt es keine Probleme, da Remoting im Gegensatz zu WCF von einer heilen 100% .NET Welt ausgeht. Hier ein kleines Beispiel wie leicht und intuitiv der Einsatz von Remoting sein kann: Remoting-Helfer
..., da sich meine Netzwerk-Klassen mittlerweile in mehreren Großprojekten, sowohl was die Performance als auch die Flexibilität angeht, bewährt haben und ich keinen Grund sehe, jetzt WCF auszuprobieren.
Das finde ich völlig okay. Aber es ist ein Unterschied ob man die bewährten Klassen schon hat, oder noch vor der Wahl der Kommunikationstechnologie steht, für ein Projekt, welches noch gar nicht existiert. Da kommt man meistens schneller zu guten Ergebnissen, wenn man etwas fertiges "von der Stange" nimmt.
Zumindest muss man bei WCF keine 20 kryptischen Konfigurationsstrukturen befüllen - teilweise mit untypisierten Listen, in denen bestimmte Objekte in der richtigen Reihenfolge drin stecken müssen - um überhaupt eine Connection hinzubekommen.
Du meinst damit vermutlich die Hashtable, die zur Übergabe von Channel-Einstellungen verwent wird. Das muss man nicht so machen! Es geht auch alles per App.config. Ist auch seit .NET 2.0 sehr gut dokumentiert (das war früher allerdings nicht so) MSDN: Schema für Remoteeinstellungen.
Aber selbst wenn Du die Konfiguration per Code machst, spielt die Reihenfolge der Einstellungen in der Hashtable keine Rolle.
Was WCF angeht, muss ich Dir wiedersprechen. Die Konfiguration von WCF ist sehr komplex und alles andere als intuitiv. Schau Dir mal das Konfigurationsschema von WCF hier an MSDN: WCF Konfigurationsschema und vergleiche es mit dem oben von Remoting. Von "angenehmer" kann da nicht die rede sein (zumindest wenn man über "Hello World" hinausgeht).
Versteh mich nicht falsch. WCF ist nicht schlecht. Vor allem, wenn man interoperabel sein muss oder generell Internet-Anwendungen erstellt. Für einfache .NET zu .NET Kommunikation ist es aber viel zu umständlich und erlegt dem Entwickler entkoppeltes Programmiermodell auf, was bei einer großen heterogenen Anwendung zwar absolut sinnvoll ist, aber im .NET zu .NET LAN-Szenario nur unnötige Komplexität und damit Kosten mit sich bringt.
Auch callbacks / events scheinen mit WCF mit deutlich weniger Daumenschrauben nutzbar zu sein als bei Remoting. Insofern zumindest was die Usability angeht ein Schritt in die richtige Richtung.
Das kommt auf den Blickwinkel an. Bei Remoting funktionieren Callbacks automatisch, ohne dass man etwas tun muss (außer clientseitig einen TcpChannel statt eines TcpClientChannel zu registrieren). Bei WCF muss man für jeden Callback explizit Code hinschreiben. WCF raubt so einiges an Flexibilität.
Von Daumenschrauben kann bei Remoting also nicht die Rede sein, sondern eher bei WCF. Remoting zwingt einem weder dazu irgendwelche Maximalwerte für Message Quotas einzuhalten, noch Kopfstände wegen Callbacks zu machen, noch sonst was. Remoting funktioniert einfach und unkompliziert.
Hallo s0h0,
die Datenkontrakte bei WCF werden serialisiert und übers Netzwerk übertragen. Das heißt, dass der Client eine Kopie der Collection bekommt. Diese Kopie liegt nun im Arbeitsspeicher des Client-Computers und hat mit dem ursprünglichen Objekt auf dem Server nichts mehr zu tun!
Du musst eine Save-Methode in Deinen WCF-Dienst einbauen, welche die geänderten Daten entgegen nimmt. Diese musst Du am Client explizit dann aufrufen, wenn Du Änderungen übers Netzwerk zurück zum Server übertragen willst.
Das ADO.NET Entity Framework eigent sich nicht gut für verteilte Anwendungen. Deshalb möchte ich Dir empfehlen, das lieber mit typisierten DataSets zu machen. Hintergünde dazu findest Du hier: Eine kleine Geschichte zum Thema RowState und OR-Mapper
Mit dezentralem Server meine ich einen standard dedicated Server oder vServer. Das macht in Sachen Anbindung, Verfügbarkeit und Kosten den meisten Sinn.
Der Server steht also bei einem Provider? Deshalb PHP, da das Hosting dafür sehr günstig ist.
Die PHP Anwendung gibt es ebenfalls noch nicht. Ich würde wahrscheinlich eine Plain-HTTP Lösung mit einfacher XML Ausgabe vorziehen. Das ganze könnte ich gut mit einem MVC Framework wie beispielsweise CakePHP umsetzen, womit es später nicht so aufwendig wäre noch eine komplette Web-Version nachzuschieben.
PHP und C# sind ganz verschiedene Welten. Es gibt auch kein gemeinsames Typsystem usw. Ich würde mir gut überlegen, ob ich ein neues Projekt von vornherein gleich auf verschiedenen Platformen stellen würde. Mit einer 100% .NET Lösung (also auch mit .NET Server) hast Du am Ende ein System, wo alles zusammenspielt, ohne Kompromisse eingehen zu müssen. Für ein paar Mücken mehr, bekommst Du auch einen Windows-Server bei einem ISP, der .NET Webdienste (SOAP) hosten kann. Auch wenn Du später ein Web-Frontend nachschieben willst, kannst Du das mit ASP.NET machen.
Was den Server angeht, möchte ich mich meinem Vorredner anschließen, und Dir WCF empfehlen. Selbst wenn Du Dich doch für PHP entscheidest, kannst Du WCF für die Anbindung des C#-Clients an den PHP-Server verwenden. Du solltest dann aber besser SOAP statt plain-HTTP einsetzen, da dafür die Unterstützung besser ist. Es gibt auch für PHP einige gute SOAP-Erweiterungen.
Was für Möglichkeiten hat C# denn, um Datenquellen möglichst so flexibel anzusprechen, dass man diese später mit möglichst wenig Aufwand austauschen kann? Meine Traumvorstellung wäre das ich die HTTP/XML Datenquelle später bequem durch eine lokale Sqlite Datenbank ersetzen kann. Ich glaube aber nicht das ein DataTableAdapter dafür geeignet ist.
Mit DataSets hast Du neutrale Datencontainer, die von beliebigen Datenquellen befüllt werden können (über entsprechende DataAdapter oder bei Bedarf auch manuell). DataSets haben auch gute XML-Unterstützung (auch XML-Schema). Wenn Du Typsicherheit haben willst (OR-Mapping), kannst Du mit dem DataSet-Designer auch typisierte DataSets erzeugen.
Linq2SQL und EntityFramework eignen sich nur sehr eingeschränkt für verteilte Anwendungen, da die erzeugten Business-Objekte keinen Zeilenstatus haben (sie wissen nicht, ob sie neu, geändert oder gelöscht sind). DataSets sind dagegen für verteilte Szenarien und auch für Offline-Clients ausgelegt. Wer LINQ mag, kann das auch mit DataSets nutzen, denn es gibt auch Linq2DataSet.
Hallo Nokinger,
soweit ich weiß, speichert Windows keine Informationen darüber, wie der StandBy-Modus ausgelöst wurde (Irrtümer vorbehalten).
Warum ist das in Deinem Fall so wichtig? Die Auswirkungen sind doch die Selben.
Hallo martl,
welche Bestandteile des Projekts sind den bereits vorhanden?
Gibt es diese PHP Serveranwendung schon, oder wird der erst noch entwickelt.
Was meinst Du mit "dezentralem Server"?
Was hat die PHP Serveranwendung für eine API (SOAP, REST, Plain-HTTP, AJAX)?
Was verstehst Du unter "XMLs"?
Was ist der Zweck dieser Software im praktischen Sinne?
Wie sind die "Daten" beschaffen und strukturiert?
Ich brauche mehr Informationen über das Projekt, um Dir sinnvoll weiterhelfen zu können.
Hallo karlstrohmann,
Word kann seit Version 2003 auch alles verlustfrei in XML (WordML) speichern (Das von telnet angesprochene DOCX-Format kam erst mit Office 2007). XML kann natürlich auch ohne Word vom Server eingelsen werden. Das bringt Dir natürlich nur dann etwas, wenn Du Einfluß darauf hast, wie die Word-Dokumente erstellt werden.
Hallo GKA,
Du kannst ein mehrspaltiges Layout einrichten. Das verhält sich dann ähnlich wie eine Tageszeitung. Alleringds würden Deine Kategorieen zuerst nach unten und dann - wenn die Spalte voll ist, nach rechts aufgefüllt.
Falls das für Deine Zwecke auch reicht: TechNet: Writing Multi column reports
Ansonsten musst Du Dir mit einem Trick behelfen. Du musst Die Daten so vorformatieren (z.B. per SQL), dass für jede Spalte eigene Felder im DataSet vorhanden sind. Dann kannst Du ein normales Report Table Control verwenden und die Spalten dort so anlegen und binden, wie Du es möchtest.
Wenn Deine Datenstruktur z.B. momentan so aussieht:
Kategorie
Produkt
Anzahl (SUM via GROUP BY)
... dann müsstest Du das in etwa so umformatieren
Kategorie1
Produkt1
Anzahl1 (SUM via GROUP BY)
Kategorie2
Produkt2
Anzahl2 (SUM via GROUP BY)
Kategorie3
Produkt3
Anzahl3 (SUM via GROUP BY)
Wenn SQL nicht zur Debatte steht, kannst Du auch vor den Bericht eine Präprozessor-Methode hängen, welche die Daten per C#-Code mit ein paar Schleifchen auf die 3 spaltige Datenstruktur umformatiert.
Hallo Marcel064,
Du solltest überprüfen, ob die entsprechenden Window-Messages auch beim Shkwave-Steuerelement ankommen. Visual Studio enthält das Tool Spy++. Damit kannst Du das ganz leicht machen.
Hallo rock4k,
es gibt einen Service Pack für debn Report Viewer, der unter anderem Probleme mit der Zeichendarstellung unter Windows XP beheben soll:
Microsoft: ReportViewer 2008 SP1
Hier ist der KB-Artikel zum Problem (bezieht sich auf SQL Reporting Services, aber das ist die selbe Engine, deshalb passt das schon): Incorrect characters appear in a SQL Server Reporting Services report after you export it to a PDF file
Du solltest auch prüfen, ob die Schriftaret Arial korrekt installiert ist. Ist zwar eine Windows-Standardschriftart. Aber vielleicht wurde sie ja deinstalliert. Halte ich zwar für unwahrscheinlich, wäre aber die einfachste Erklärung.
Hallo prickelpit96,
hier ist ein Besipiel, wie Du unter anderem die USB Device ID bekommst: Getting the USB Devices Information using WM
Die ID bekommst Du vom USB Controler und nicht vom Gerät selbst.
Remoting ist eine Technologie um entfernte Methodenaufrufe durchzuführen. Ein Client ruft dabei eine beliebige Methode eines Objekts auf, welches auf einem Server lebt. Beschränkungen gibt es dabei nicht, außer dass das Objekt auf dem Server direkt oder indirekt von MarshalByRefObj abgeleitet sein muss.
Remoting versucht die Netzwerkkommunikation so weit wie irgend möglich zu kapseln. Wer RPC machen will, der möchte, dass sich die Methodenaufrufe wie lokale Stack basierte Aufrufe anfühlen. Man möchte sich nicht mit Sockets und den darunterliegenden Protokollen beschäftigen müssen, deshalb entscheidet man sich für RPC mit Remoting.
Wer direkt Einfluss auf die Netzwerkkommunikation nehmen möchte, der sollte sich nicht für Remoting entscheiden. Dafür gibt es die Tools aus dem System.Net Namensraum. Damit kann man alles machen, was im Rahmen der Netzwerkprotokolle möglich ist. Dafür ist die Implementierung wesentlic aufwändiger. Ob Socket basierte Netzwerkprogrammierung nötig ist, muss jeder selber für sein konkretes Projekt entscheiden.
Wenn Dir Remoting zu viele Beschränkungen hat, dann trifft das wohl auch für WCF zu, denn auch WCF ist eine RPC-Technologie, welche die Netzwerkkommunikation kapselt.
Mit der Lizenz hat das nichts zu tun (Natürlich wird für jeden Benutzer, der Funktionen einer Office-Lizenz verwendet auch eine Lizenz benötigt; Aber das wäre ja auch bei der Installation auf einem Webserver kein Problem).
Warum ich sage, dass es böse ist, hat technische Gründe. Office-Anwendungen sind COM-Anwendungen und unterstützen kein Multithreading! Da ein Webserver aber viele Anfragen "gleichzeitig" verarbeiten kann und jede Anfrage in einem separaten Thread abgearbeitet wird, steht Multithreading bei ASP.NET auf jeden Fall auf dem Plan. Es sei denn jede Anfrage öffnet ihre eigene Instanz der jeweiligen Office-Installation. Das wäre aber auch sehr bedenklich und der Skalierbarkeit nicht unbedingt zuträglich, wenn für jede Anfrage auf dem Webserver z.B. eine eigene Excel-Instanz geladen werden müsste.
Das könnte man aber mit schnellen Festplatten und viel Arbeitsspeicher am Server ausgleichen.
Das größte Hinterdins für einen Server-Einsatz ist aber, dass Office-Anwendungen nicht für die unbeafsichtigte Automatisierung entworfen wurden. Man kann Office-Anwendunegn zwar über ihr COM-Objektmodell fernsteuern, aber das ändert nichts an der Tatsache, dass die Anwendung an einigen Stellen auf Eingaben vom Benutzer wartet (z.B. Meldungsfenster, Dialoge, etc.). Auf einem Webserver ist aber keiner da, der den OK-Button eines solchen Dialoges anklickt. Ein Beispiel dafür sind z.B. Hinweismeldungen bei Word-Serienbriefen.
Der Einsatz von Office auf einem Webserver ist deshalb nicht empfehlenswert.
Vor allem weil es andere Lösungsansätze gibt, die sehr gut funktionieren.
Hallo IngoKo,
Die PIAs sind nur .NET Wrapper für das COM-Objektmodell von Office. Office muss natürlich trotzdem installiert sein.
Aber unabhängig davon: OFFICE GEHÖRT NIEMALS AUF EINEN SERVER!
BÖSE! JEHOVA!
Du kannst die XML-Formate verwenden, um auf dem Server Office-Dokumente zu erstellen und zu bearbeiten, ohne dass Office installiert sein muss.
Schau mal hier:
http://dotnet-snippets.de/dns/excel-export-ohne-excel-auch-fuer-web-SID632.aspx
http://www.carlosag.net/Tools/ExcelXmlWriter/
http://msdn.microsoft.com/en-us/library/aa212812%28office.11%29.aspx
Hallo Servus,
Ich habe physikalisch keinen Zugriff auf die Daten der Sharepoint Webseite.
Ähm, was heißt, Du hast keinen Zugriff?
Du brauchst bestimmte Berechtigungen, um eine Seite bearbeiten zu dürfen. Um ASP.NET Code einzufügen brauchst Du vermutlich (habe mit SP2010 noch nicht gearbeitet) sogar weitreichende Rechte.
Schau mal: http://www.sharepointoverflow.com/questions/2154/unable-to-edit-site-in-sharepoint-designer-2010
Weiß eigentlich jemand zufällig ob das IpcChannel Rechnerglobal oder Benutzerlokal ist?
Rechnerglobal!
Hallo Rushmore,
bei .NET Remoting geht alles, was Du Dir wünschst out-of-the-box. Du würdest den Mandantenschlüssel einfach am Client in den Aufrufkontext (CallContext) legen und schon würde der Schlüssel implizit zum Server übertragen. Vor allem würde er auch vom ersten aufgerufenen Service zum weiteren Services weitergeleitet, die wiederum vom ersten Service aufgerufen werden.
Bei WCF gibt es keinen CallContext mehr. Stattdessen gibt es einen OperationContext. Der funktioniert aber nur für genau einen einzigen Methodenaufruf. Also spätestens beim 2. Service in der Aufrufkette sitzt DU bei WCF wieder auf dem Trockenen.
Das Problem an WCF ist, dass man alles auf Standards und Interoperabilität ausgelegt hat. Wenn ich z.B. mit einem Java-Webservice kommunizieren, dann kann ich natürlich keinen CallContext (a la Remoting) voraussetzen, da dieser z.B. im SOAP-Standard nicht vorgesehen ist (Wenn ich aber 100% reines .NET habe und sowohl Server als auch Client selber schreibe, dann ärgere ich mich darüber, dass ich bei WCF trotzdem mit ähnlichen Beschränkungen zu kämpfen habe, wie bei einem interoperablen Projekt).
Nichts desto trotz gibt es auch bei WCF Mittel und Wege, um ans Ziel zu kommen (Allerdings muss man dafür jede Menge Code hinschreiben). Für eigene Credentials findest Du hier ein Beispiel: MSDN: Custom WCF Credentials
Damit die Weiterleitung funktioniert, musst Du vermutlich diverse Behaviors schreiben. Hab ich allerdings noch nicht gemacht. Es gibt auch kein Beispiel dazu (zumindest habe ich noch keines gefunden). Vielleicht inspiriert Dich folgende Seite: MSDN: Extending WCF
Oder Du verwendest einfach das gute alte .NET Remoting. Das tut einfach was es soll, ohne dass man Kopfstände machen muss. Neues muss nicht besser sein. So ist es auch mit WCF. Zumindest wenn man einfach .NET zu .NET Kommunikation machen will.
LifetimeService steuert die Lebenszeit des Objekts, nicht die der Socketverbindung!
Von Murks kann übrigens nicht die Rede sein. Allerdings tun sich Leute, die gewohnt sind direkt auf Socket-Ebene zu arbeiten, mit Remoting schwer, da Remoting die Netzwerkkommunikation komplett kapselt. Diese Leute haben dann das Gefühl nicht mehr die Kontrolle zu haben oder fühlen sich vom Remoting-Framework bevormundet.
Aus dem selben Grund gibt es auch Leute, die ihr Datenbanksystem selber schreiben.