810 likes | 824 Views
Understand the design decisions in the .NET framework and use patterns to describe architectural aspects of systems.
E N D
Patterns in .NET- ACCU 2002 - Markus Voelter, CTO, MATHEMA AG voelter@acm.org http://www.voelter.de slides (mostly ) by Michael Stal, Senior Principal Engineer SIEMENS AG, Dept. CT SE 2 E-Mail: mailto:Michael.Stal@mchp.siemens.de Web: http://www.stal.de
Goal of the Presentation • Understand some design decisions in the .NET framework • Use of Patterns to describe architectural aspects of systems • NOT: Introduction to .NET Markus Voelter/Michael Stal – Patterns in .NET
Agenda • Motivation • Architectural Aspects • Web-Services • .NET Remoting • Collections • Forms and Controls • Threading • Interop • Summary • Literature Markus Voelter/Michael Stal – Patterns in .NET
System.Web System.Windows.Forms Base Class Library Support Services UI Design ComponentModel Description HtmlControls Thread Support COM Marshaler Discovery WebControls Protocols System.Drawing Type Checker Exception Manager Caching Security Drawing2D Printing Configuration SessionState Imaging Text Security Engine Debug Engine System.Data System.Xml ADO SQL XSLT Serialization IL to Native Compilers Code Manager Garbage Collector Design SQLTypes XPath System Collections IO Security Runtime InteropServices Class Loader Configuration Net ServiceProcess Remoting Diagnostics Reflection Text Serialization Globalization Resources Threading Motivation • .NET represents a completely new infrastructure for Windows development and a new Lifestyle. CLR Markus Voelter/Michael Stal – Patterns in .NET
Motivation (cont‘d) • Compared to „legacy“ Windows development, .NET simplifies matters significantly. • But .NET is voluminous, it‘s easy to lose sight of the big picture • For efficient .NET development, it‘s not enough to know the APIs, you need to understand the internal architecture of .NET • This presentation tries to answer not the how, but the why from an architectural viewpoint. Markus Voelter/Michael Stal – Patterns in .NET
Subject Observer 1 Observer 2 ConcreteObserver House1 Door_A; Window_1a Window_1b ... update doSomething attach(this) depends on depends on is presented as attach(this) setData notify update getData update getData What is a pattern? Problem A Pattern… … represents a concrete solution (template) for recurring problems in the respective domain. … takes into account the forces that drive the solution. … documents expertise ... specifies concepts on top of classes and objects (such as collaborations, interactions) … provides a common vocabulary and a common understanding of concepts ... Adresses specific quality properties of the solution. Observer Solution Subject Observer * state observerList update attach detach notify setData getData state = X; notify(); s->getData() for all observersin observerList do notify(); Markus Voelter/Michael Stal – Patterns in .NET
Web Services Markus Voelter/Michael Stal – Patterns in .NET
The Web is the Computer • We need an infrastructure, that • allows web-based communication among components • provides location transparency • allows to add, remove or to change services dynamically • and keeps all the gory details hidden from the programmer Markus Voelter/Michael Stal – Patterns in .NET
Idea: Web Services • A Web service represents a unit of business, application, or system functionality that can be accessed over the Web (Internet, Intranet, or Extranet) • they are accessible over the Web • they expose an XML interface • they can be registered and located through a Web service registry • they communicate using XML messages over standard Web protocols • they support loosely-coupled connections between systems • Web services focus on business-to-consumer, business-to-business, department-to-department, peer-to-peer interactions. • Consumers of these services may be humans or application programs or other Web services. • In theory, it doesn‘t matter what technologies are used to build Web services, because all Web service environments can interoperate using XML protocols. (Sun Microsystems) Markus Voelter/Michael Stal – Patterns in .NET
Broker-based architecture Message exchange Message exchange Broker 1 * 1 Client-side Proxy Server-side Proxy * register_server find_server establish_communication marshal unmarshal receive_result service(proxy) marshal unmarshal dispatch receive_request * calls * calls 1 1 Client Service call_service_p start_task start_up main_loop service(impl.) Markus Voelter/Michael Stal – Patterns in .NET
Client Server Client Proxy Broker ServerProxy register_service start_up method (proxy) assigned port locate_server server port marshal receive_request unmarshal dispatch method (impl.) result marshal receive_result unmarshal result Broker: Dynamics Markus Voelter/Michael Stal – Patterns in .NET
Proxy Service AbstractService service service service The Proxy Pattern forms the basis Solution Provide a placeholder for the object through which clients can access it AService implements the object which is not directly accessible. A Proxy represents the Service and ensures the correct access to it. The Proxy offers the same interface as the Service. Clients use the Proxy to get access to the Service. Client 1 1 Markus Voelter/Michael Stal – Patterns in .NET
service pre-processing: marshaling post-processing: unmarshaling service Proxy: Dynamics Client Proxy Service Markus Voelter/Michael Stal – Patterns in .NET
Step 1: The transport protocol • A protocol defines syntax, semantics and flow of messages among peers. • For a web-based protocol, we need: • HTTP and other internet protocols as transport layer • „self-describing data representation format“ Kurz: XML. • In Details: every invocation and its response is rendered as an XML document sent over the wire using HTTP et. al. • Welcome in the world of SOAP. Markus Voelter/Michael Stal – Patterns in .NET
Step 1 – Example • Example for a SOAP Message: <soap:Envelope> <soap:Header> <transaction> <soap:mustUnderstandstand=„true“ xmlns=„http://tx.com“> <id> 12345678 </id> </transaction> <soap:Header> <soap:Body> <m:getPhoneNumber> <theName> Bill Gates </theName> <m:/getPhoneNumber> </soap:Body> </soap:Envelope> SOAP messages are bracketed by envelopes headers are optional this feature must be supported by the receiver message body Markus Voelter/Michael Stal – Patterns in .NET
Step 2: Description Language • We need a description of what a webservice provides • The available operations and their signature, including complex types • How and where a service can be accessed • We also use XML for this purpose in the form of WSDL, the Web Service Description Language (WSDL). • Warning: WSDL does not describe any semantics (as with practically all interface definition languages) Markus Voelter/Michael Stal – Patterns in .NET
1. search for web service 2. return service URL 3. read service description 5. forward request to service 4. send request using SOAP over HTTP 7. send result using SOAP over HTTP 6. return result Step 3: How to find the services • UDDI is a global registry • Registration possible at any node • Registrations replicated at daily basis • Common SOAP protocol used UDDI Publisher API Inquiry API Description of Web Service (WSDL) Web Server Client Web Service Markus Voelter/Michael Stal – Patterns in .NET
UDDI as a universal registry White Pages Yellow Pages Green Pages • Registry acessible by name • Listing of all service providers including details • Contact information (Webservices, Telephone,…) • Mercantile directory • Lookups based on several taxonomies (location, kind of service, domain, …) • Points to White Pages • Information on the business model of the business • Technical details about the provided web services • Information on business processes Markus Voelter/Michael Stal – Patterns in .NET
Client Proxy Server Proxy .NET provides tools... • The tools generate glue code to „connect“ to the web middleware: • Client Proxies um den Client mit dem Dienst zu verbinden. • Server Proxies zur nahtlosen Dienstintegration. • also generate WSDL from server objects WSDL Markus Voelter/Michael Stal – Patterns in .NET
Example in .NET • A simple Webservice namespace EuroDMConversion { public class Converter: System.Web.Services.WebService { [WebMethod] public double DM_to_Euro(double value) { return value / 1.95583; } [WebMethod] public double Euro_to_DM(double value) { return value * 1.95583; } } } Markus Voelter/Michael Stal – Patterns in .NET
Example in .NET (cont‘d.) • A Demo-Client: private void buttonClk(object sender, System.EventArgs e) { if (textBox1.Text.Equals("")) { textBox1.Text = "0"; return; } localhost.Service1 s1 = new localhost.Service1(); textBox2.Text = s1.DM_to_Euro(double.Parse(textBox1.Text)); } Markus Voelter/Michael Stal – Patterns in .NET
.NET Remoting Markus Voelter/Michael Stal – Patterns in .NET
What is.NET Remoting • .NET Remoting is the true successor to DCOM. • A framework to allow (remote) applications to communicate • Flexibility: Almost everything can be exchanged or extended (Protokoll, Marshaler, ...). • Contexts as in COM+ are supported! • With a very simple API! Markus Voelter/Michael Stal – Patterns in .NET
Remoting from 10.000 ft Application Domain A Application Domain B Client Servant Transparent Proxy Real Proxy Object Context Sinks Envoy Sinks Server Context Sinks Network Channels Channels Formatters Formatters Markus Voelter/Michael Stal – Patterns in .NET
An Example • The Remote Object: public class Grid : System.MarshalByRefObject { const int LENGTH = 10; double [,] matrix = new double[LENGTH,LENGTH]; public int Length { get { return LENGTH; } } public double this[int i1, int i2] { set { if (OutOfBounds(i1,i2)) throw new ArgumentException(); else matrix[i1,i2] = value; } get { if (OutOfBounds(i1,i2)) throw new ArgumentException(); else return matrix[i1,i2]; } } bool OutOfBounds(int i1, int i2) { return (i1 < 0) || (i1 >= LENGTH) || (i2 < 0) || (i2 >= LENGTH) ? true : false; } } Markus Voelter/Michael Stal – Patterns in .NET
An Example cont‘d • The Server: class Server { static void Main(string[] args) { TcpServerChannel ch = new TcpServerChannel(8888); ChannelServices.RegisterChannel(ch); RemotingConfiguration.RegisterWellKnownServiceType (typeof(Grid), "Grid", WellKnownObjectMode.Singleton); while(true); // loop forever } } Markus Voelter/Michael Stal – Patterns in .NET
An Example cont‘d • A Client: class Client { static void Main(string[] args) { ChannelServices.RegisterChannel(new TcpClientChannel()); Grid myGrid = (Grid)Activator.GetObject(typeof(Grid), "tcp://localhost:8888/Grid"); if (myGrid == null) { Console.WriteLine("Could not connect!"); return; } for (int i = 0; i < myGrid.Length; i++) { for (int j = 0; j < myGrid.Length; j++) { myGrid[i,j] = (double)(i*10 + j); } } } } Markus Voelter/Michael Stal – Patterns in .NET
Design of .NET Remoting • .NET Remoting is also based on the Broker pattern Message exchange Message exchange Broker 1 * 1 Client-side Proxy Server-side Proxy * register_server find_server establish_communication marshal unmarshal receive_result service(proxy) marshal unmarshal dispatch receive_request * calls * calls 1 1 Client Service call_service_p start_task start_up main_loop service(impl.) Markus Voelter/Michael Stal – Patterns in .NET
Addition of Context information • (Call) Contexts are data items that are automatically transported with a remote invocation. • It is not part of the method signature • Client and Server both have access to the data, typically inside „technical frameworks“ • Typically, security or transaction information is transferred in contexts • How can we make sure context data is transparently added to remote invocations in .NET? Markus Voelter/Michael Stal – Patterns in .NET
Runtime runEventLoop attachInterceptor manage interceptors Solutions: Interceptors Introduce interceptors that can be attached to a system for handling particular events. Whenever an event occurs, the associated interceptors get automatically called: Runtime represents the framework to which we like to attach interceptors. It is responsible for managing and calling interceptors. Concrete Interceptors implement the event handler for the system specific events they have subscribed for. Environment contains information about the event and allows to modify the system behavior after interceptor completion. The container is responsible for registering its interceptors with the runtime. provide Environment Abstract Interceptor handleEvent callback attach Concrete Interceptor Container * handleEvent Markus Voelter/Michael Stal – Patterns in .NET
runEventLoop create Interceptor attach Interceptor Place interceptor in internal interceptor map Look for registered interceptors event create Env handleEvent Env Dynamics Runtime Application Markus Voelter/Michael Stal – Patterns in .NET
Chaining of Interceptors • We need a mechanism to chain several interceptors so that each gets a chance to do something • A tight coupling of sender and receiver should be avoided • How can we achieve this? • Solution: Chain of Responsibility Pattern: aHandler successor request request aHandler successor request aHandler Markus Voelter/Michael Stal – Patterns in .NET
Avoidance of Dependencies • .NET Remoting should be independent of • The transport protocol • Which marshalling strategy is used • In a Broker-Architecture, the proxies are responsible for the communication. • How can the proxies be decoupled from this responsibility? Markus Voelter/Michael Stal – Patterns in .NET
Forwarder Forwarder Receiver Receiver marshal deliver sendMessage receive unmarshal receiveMessage marshal deliver sendMessage receive unmarshal receiveMessage Peer 2 Peer 1 service service Forwarder-Receiver • Solution: Additional components There Here Markus Voelter/Michael Stal – Patterns in .NET
unmarshal receive marshal Forwarder-Receiver (cont‘d) • Dynamics Peer 1 Forwarder 1 Receiver 1 Receiver 2 Forwarder 2 Peer 2 recvMsg sendMsg deliver Message Markus Voelter/Michael Stal – Patterns in .NET
Plug and Play • In .NET Remoting Channels and Formatters should be exchangable • TCP-Channels and HTTP Channels • SOAP Formatter and binary Formatter • How is pluggability reached without consequences for the upper layers? Markus Voelter/Michael Stal – Patterns in .NET
Strategy dispatch Solution: Strategy Pattern Encapsulate each strategy as a separate object: Strategy declares an interface common to all supported implementation. Concrete Strategies implement the strategy interface for a specific implementation. Context offers a service to clients and is configured with a concrete implementation. Context ConcreteStrategy dispatch Markus Voelter/Michael Stal – Patterns in .NET
Strategy in .NET Remoting • The Formatters in .NET implement die the IRemotingFormatter interface • Serialize() • Deserialize(). • A Formater Sink Provider implements the interface IServerChannelSinkProvider (Server) or IClientChannelSinkProvider (Client). • A sending channel implemens IChannelSender (Forwarder) and a receiving channel implements IChannelReceiver (Receiver). • A channel can also play both roles by implementing both interfaces Markus Voelter/Michael Stal – Patterns in .NET
Asynchronous Communication • .NET and .NET Remoting technically only support synchronous invocations • Caller has to wait until an invocation returns • It cannot do anything else in the meantime (in that same threat, that is!) Markus Voelter/Michael Stal – Patterns in .NET
<<send>> <<write>> <<route>> <<read>> <<recv>> Solution: Asynchronousity using message layer Introduce intermediary queues between senders and receivers : Queuesare used to store messages persistently. They cooperate with other queues for message routing. Messages are objects send from a sender to a receiver. A sender sends messages, while a receiver receives them. A Message API is provided for senders and receivers to send/recv messages. Sender Message API Queue store forward remove Message Queue store forward remove Receiver Message API Markus Voelter/Michael Stal – Patterns in .NET
create Message send Message Message store Message forward Receiver create receive receive Message Message read Dynamics Sender Message API Queue Queue Message API Markus Voelter/Michael Stal – Patterns in .NET
The developer‘s view • Developers prefer a (synchronous) RPC-style model • We separate calls into two messages • Requests contain in/in-out arguments • Results contain out/inout arguments and results • Callbacks or polling technique to receive results (futures) Markus Voelter/Michael Stal – Patterns in .NET
1. method() 5. result 4. method() 8. return 2. enqueue 3. dequeue 6. enqueue 7. dequeue Developer‘s view (cont‘d) Client Client Proxy (Recorder) Queue Proxy (Player) Markus Voelter/Michael Stal – Patterns in .NET
Asynchronous Communication in .NET • First, a synchronous call using a delegate public delegate int WorkDelegate(string s); public int DoWork(string s) { Console.WriteLine("Doing work ...{0}", s); return 42; } public void Test() { WorkDelegate w = new WorkDelegate(DoWork); int i = w("Synchronous Hallo"); // synch call Console.WriteLine("Result = {0}", i.ToString()); ... Markus Voelter/Michael Stal – Patterns in .NET
Asynchronous Communication in .NET (cont‘d) • Now asynchronously with polling public void Test() { // call it asynchronously IAsyncResult ar = w.BeginInvoke( "Asynchronous Hallo with Polling", null, null); ar.AsyncWaitHandle.WaitOne(); // wait until ready i = w.EndInvoke(ar); Console.WriteLine("Result = {0}", i.ToString()); } Markus Voelter/Michael Stal – Patterns in .NET
Asynchronous Communication in .NET (cont‘d) • Now Asynch with callback private void CallCompleted(IAsyncResult ar) { WorkDelegate w = (WorkDelegate)((AsyncResult)ar).AsyncDelegate; int i = w.EndInvoke(ar); Console.WriteLine("Result = {0}", i.ToString()); } public void Test() { // call it asynchronously with callback w.BeginInvoke("Asynchronous Hallo with Callback", new AsyncCallback(CallCompleted), null); } Markus Voelter/Michael Stal – Patterns in .NET
Problem: Remote object Activation • Resources such as remote objects should only be instantiated when they are actually required. • There needs to be a way to activate objects when they are needed! • So: How do we implement an activation strategy? Markus Voelter/Michael Stal – Patterns in .NET
Activator Activation Table Service Client (de)activate getService register unregister onShutdown insertEntry removeEntry lookupEntry changeEntry service shutdown Solution: Activator Pattern Integrate activation code for automatically starting up server implementations. Provide necessary information in tables: Upon incoming requests the Activator looks up whether a target object is already active. If the object is not running it activates the implementation. The Activation Table stores associations between services and their physical location. The Clientuses the Activator to get service access. A Service implements a specific type of functionality that it provides to clients. useService Get Service Markus Voelter/Michael Stal – Patterns in .NET
getService lookupEntry [not active] activate Implementation changeEntry result object port service onShutdown changeEntry Dynamics Activator Activ. Table Client Markus Voelter/Michael Stal – Patterns in .NET
Deactivation in .NET • Question: How do I make sure that activated remote objects are eventually deactivated (freed)? • Answer: Lease-Pattern • The object is only active for a specific period of time • When the lease expires, the object is freed. • The release is renewed based on certain criteria: • A method invocation by the client • … Markus Voelter/Michael Stal – Patterns in .NET