bonn-to-code.net die appdomain das unbekannte wesen? 19.11.2013 dr. jochen manns...
TRANSCRIPT
bonn-to-code.netbonn-to-code.netbonn-to-code.netbonn-to-code.net
Die AppDomainDas unbekannte Wesen?
Die AppDomainDas unbekannte Wesen?
19.11.2013
Dr. Jochen Manns
EMail: [email protected]: http://www.jochen.jochen-manns.de
bonn-to-code.netbonn-to-code.net
AgendaAgenda
Kleine Einführung AppDomains und die Anwendung Varianten von Marshalling
Marshalling in der Praxis By Value By Reference It depends…
bonn-to-code.netbonn-to-code.net
ÜbersichtÜbersicht
bonn-to-code.netbonn-to-code.net
.NET und die AppDomain.NET und die AppDomain
Jeder Code läuft in einer AppDomain Threads sind ein orthogonales Konzept
Mindestens eine AppDomain pro Prozess Default AppDomain wird beim Starten
angelegt Weitere müssen explizit erzeugt werden
Im Normallfall unsichtbar Nur die Default AppDomain Keine Notwendigkeit, AppDomains zu
kennen
bonn-to-code.netbonn-to-code.net
Warum benutzt man AppDomains?Warum benutzt man AppDomains?
Eine Art Prozess im Windows Prozess In .NET hochgradig isoliert
Nativer Code kennt keine Grenzen Eigene Sicherheitsregel
Vor allem Ausführungspfade für Bibliotheken
Erweiterungskonzepte / PlugIns Sichere, abgeschirmte Umgebung der
PlugIns Kontrollierte Schnittstelle zum Host
Zeitweises Laden von Bibliotheken
bonn-to-code.netbonn-to-code.net
ASP.NET und IISASP.NET und IIS
Ein Prozess pro Application Pool Eine AppDomain pro virtuellem
Verzeichnis Mehrere virtuelle Verzeichnisse pro Pool Trotzdem vollständig isoliert (.NET)
ASP.NET Hosting ApplicationHost Klasse Volle ASP.NET Laufzeitumgebung
Web.Config, WebApi, MVC, ASPX, ASMX, … Separate AppDomain für den Host
bonn-to-code.netbonn-to-code.net
KommunikationKommunikation
bonn-to-code.netbonn-to-code.net
Kommunikation und MarshallingKommunikation und Marshalling
Isolation kontrolliert durchbrechen Proxy / Stub Objekte
Proxy in der steuernden AppDomain (Host) Stub in der untergeordnete AppDomain
Inter-AppDomain Methodenaufrufe AppDomain Wechsel auf einem einzigen
Thread Indirekte Aufrufe kosten Zeit
Was ist aber mit Daten / Objekten? Marshalling in zwei Varianten
bonn-to-code.netbonn-to-code.net
Marshal By ValueMarshal By Value
Vollständige Übertragung Keine Kommunikation über die Daten Hohe Unabhängigkeit der AppDomains Datenaustausch, evtl. umfangreich
[Serializable] Binäre Variante Berücksichtigt alle .NET Fields
[NonSerialized]
Zwingend für alle referenzierten Objekte
bonn-to-code.netbonn-to-code.net
Marshal By ReferenceMarshal By Reference
Proxy Referenz auf einen Stub Keine Datenübertragung Zugriff erfordern erneuten AppDomain
Wechsel Jede Codeausführung (auch der Abruf
eines .NET Fields) erfolgt in der AppDomain, in der das Objekt erzeugt wurde
Im By Value Fall wird Code immer in der AppDomain des Aufrufers ausgeführt
Ableiten von MarshalByRefObject
bonn-to-code.netbonn-to-code.net
Böse Falle Garbage CollectionBöse Falle Garbage Collection
Ein Proxy ist keine starke Referenz Der Stub muss sich vor Freigabe
schützen InitializeLifetimeService Ansonsten ist der Proxy irgendwann kaputt
bonn-to-code.netbonn-to-code.net
ASP.NET HostingASP.NET Hosting
bonn-to-code.netbonn-to-code.net
WebApi Hosting in einem DienstWebApi Hosting in einem Dienst
Datenverwaltung im Dienst Datenbank Steuerungslogik Kontrollierte Laufzeitumgebung
Remote Schnittstelle für Clients WCF WebApi Self Hosting ASP.NET Hosting
Für REST, aber auch ASPX, ASMX, … Betriebssicherheit durch Isolation
bonn-to-code.netbonn-to-code.net
Zugriff auf die Dienst AppDomainZugriff auf die Dienst AppDomain
ASP.HET Hosting über Proxy / Stub Dienst kann auf ASP.NET Laufzeit zugreifen
Sequenz immer ähnlichm_Runtime = (IASPNETProxy) ApplicationHost.CreateApplicationHost( typeof( ASPNETProxy), … );m_Runtime.SetServer( m_Server );
Dienstobjekt in ASP.NET verfügbar machen By Reference Stub lebt im Dienst Proxy kann von ASP.NET angesprochen
werden
bonn-to-code.netbonn-to-code.net
MarshallingMarshalling
bonn-to-code.netbonn-to-code.net
REST via Marshal By ReferenceREST via Marshal By Reference
[DataContract]public class ClientResponse{ [DataMember] public string Data { get; set; }}
var response = new ClientResponse { Data = proxy.Analyse( 12 ) };
• Die Antwort an den Client wird in der ASP.NET AppDomain erstellt.
• Jeder Aufruf an den Dienstproxy muss die AppDomain Grenze überschreiten.
• Alle Objekte müssen eine Überschreitung zulassen:
• By Value, wie alle einfachen .NET Klassen
• By Reference, üblicherweise eigene Klassen
• Wilder Zugriff führt zu Fehlermeldungen, gute Kontrolle!
• Die Ausführungsgeschwindigkeit kann leiden
• Besondere Vorsicht bei Listen von Objekten
• Viele Einzelzugriffe auf .NET Fields & Properties evtl. problematisch
public interface IServiceProxy { string Analyse( int depth ); }
bonn-to-code.netbonn-to-code.net
REST via Marshal By ValueREST via Marshal By Value
[Serializable]public class ServiceResponse{ public string Data { get; set; }}
var serviceResponse = proxy. Analyse( 12 );
var response = new ClientResponse { Data = serviceResponse.Data };
• Die AppDomain des Dienstes bereitet alles vor
• Die Bearbeitung findet vollständig dort statt
• In der ASP.NET AppDomain wird noch einmal umkopiert• Die Dienst AppDomain kann natürlich auch direkt das Ergebnis erzeugen• Dann muss dieses aber auch By Value sein
[DataContract, Serializable]public class ClientResponse{ [DataMember] public string Data { get; set; }}
public interface IServiceProxy { ServiceResponse Analyse( int depth ); }
public interface IServiceProxy { ClientResponse Analyse( int depth ); }
var response = proxy.Analyse( 12 );
bonn-to-code.netbonn-to-code.net
Code AbhängigkeitenCode Abhängigkeitenusing System;using System.Collections.Generic;using Sample.ClientNamespace;
namespace Sample.ServiceNamespace{ public class ServiceItem { public Service Service { get; private set; }
public string Data { get; private set; }
public ClientItem ToClient() { return new ClientItem { Data = Data }; } }
public class Service : MarshalByRefObject { private readonly List<ServiceItem> m_items = new List<ServiceItem>();
public ClientItem ToClient( int index ) { return m_items[index].ToClient(); } }}
using System;using System.Runtime.Serialization;using Sample.ServiceNamespace;
namespace Sample.ClientNamespace{ [DataContract, Serializable] public class ClientItem { public string Data { get; set; } }
public class TheController { public ClientItem GetItem( int index ) { return ASPNETRuntime.ServiceProxy.ToClient( index ); } }}
bonn-to-code.netbonn-to-code.net
EntkoppelnEntkoppeln
using System;using System.Collections.Generic;
namespace Sample.ServiceNamespace{ public class ServiceItem { public Service Service { get; private set; }
public string Data { get; private set; } }
public class Service : MarshalByRefObject { private readonly List<ServiceItem> m_items = new List<ServiceItem>();
public TClientType ToClient<TClientType>( int index, Func<ServiceItem, TClientType> factory ) { return factory( m_items[index] ); } }}
using System;using System.Runtime.Serialization;using Sample.ServiceNamespace;
namespace Sample.ClientNamespace{ public class TheController { public ClientItem GetItem( int index ) { return ASPNETRuntime.ServiceProxy.ToClient( index, ClientItem.FromService ); } }
[DataContract, Serializable] public class ClientItem { public string Data { get; set; }
public static ClientItem FromService( ServiceItem item ) { return new ClientItem { Data = item.Data }; } }}
Die statische Methode wirdin der AppDomain desDienstes ausgeführt!
bonn-to-code.netbonn-to-code.net
Marshal By Value nach BedarfMarshal By Value nach Bedarf
Mehrere By Value Varianten nutzen Je nach Kontext verschiedene Inhalte Pro REST Controller oder gar pro Methode
Gezielt mischen By Reference für äußere Objekte By Value für Detailobjekte
Querreferenzen können verloren gehen Querreferenzen lassen Datenmenge
explodieren
bonn-to-code.netbonn-to-code.net
ZusammenfassungZusammenfassung
AppDomains sind isolierte Bereiche Innerhalb eines Windows Prozesses
Methoden werden über Proxy Klassen aufgerufen
Daten werden By Value oder By Reference ausgetauscht
Beide Varianten haben Vor- und Nachteile
Hybride führen oft zur besten Lösung
Generische Methoden zur Entkoppelung