May 18, 2003
@ 10:52 PM

Still on the road.

Friday was my first scheduled office day after 2 1/2 months on the road. Now I am sitting in the CSA airport lounge in Prague (free Internet, bring cable) waiting for my flight to Bucharest. Tuesday I go to Frankfurt, then on to our TornadoCamp.NET event in Bad Ems (Germany) where I'll be for the rest of the week. As per current planning, I'll have a couple of days at home next week and then I am going to Dallas, TX for TechEd. The U.S. is country #18 on this year's list -- no, wait, been there already this year.

For TechEd I am prepping a set of new extensions for ASMX. I think ASMX doesn't do as well in regards to its support for XML Schema as it could.

Categories:

May 18, 2003
@ 04:04 PM

My talks at Microsoft TechEd in Dallas will be:

WEB404: ASP.NET Web Services Extensibility: "I didn't know you could do that!"
DEV359: Aspect Oriented Programming
DEV357: Building Distributed .NET Applications

The last one (which is likely going to be rescheduled to earlier in the week than Thursday) is the most important and ambitious one. I will try to give some guidance around the "appropriate use" of .NET Remoting, Enterprise Services and Web Services and show that there that there's no "vs." or "or" between those three technologies but an "and". I'll talk about layers and tiers, process models, security, data, objects, services -- all in a bit more than an hour.

 

Categories:

Tornado Camp .NET Applied Architecture
July 23 - 25, 2003, Hamburg, Germany
Held in English

A 3-day workshop based on the Microsoft EMEA Building Scalable Applications Tour 2003.  The first day is direct from the tour and days 2 and 3 are putting it all into practice in a hands-on workshop! Send mail to info@newtelligence.com for details.

Categories:

May 9, 2003
@ 09:09 PM
Ah, yes, C#. Umm, no, a clone.
Categories:

Maximum travel -- This past week

This week was a crazy travel week and I can't wait to be back home tonight. It's a miracle that I still have my bag and didn't miss any connections and everything worked out. Here's a brief summary of the travel ordeal:

  • Sunday afternoon: Drove from Meerbusch (Düsseldorf) to Frankfurt (2 hrs) for the first stop on the German roadshow with Jörg. Jörg took my car from there to Munich for another event.
  • Monday: Frankfurt event, went to the aiport in the afternoon to catch a flight to Oslo for the Norwegian Developer Days.
  • Tuesday: Oslo event, then to the airport to catch a 1845 flight to Frankfurt, got into Frankfurt with a 30 minute delay into the "B" gates, with my connection to Venice already boarding for 10 minutes in the "A" gates. Frankfurt is big. Ran from "B" to "A" an got to the gate just before they were closing the doors. Of course, the Venice flight ended up being in line for takeoff about 30 minutes. Got into Venice late (and miraculously still got my bag) and made it to the rental car booth about 5 minutes before the lady there would have closed shop. Got a car and drove to Trieste and then on to Portoroz in Slovenia. Got into the hotel at 0200.
  • Wednesday: Slovenian event
  • Thursday: Got up at 0500, got into the car at 0530 and drove back to Trieste airport (which isn't called Trieste Airport). Caught an 0820 plane to Munich, got there at 0930, got into a cab and was at the event location for the Munich stop of the German launch 20 minutes before my talk was due to start. At 1815 got into a cab to the aiport, boarded at 1950 for a flight to Berlin. Arrived at the hotel at around 2200
  • Friday: Berlin event, tonight at around 2000 going home to Düsseldorf. I'll be using the 19th and last flight coupon of the ticket that I had on me in the last three weeks, Scalable Applications Tour included. Next week: next ticket.

That much on "all this travel must be great fun". Being at events and talking to developers and architects is great fun, the travel part isn't, really.

Categories:

Enterprise Services Beispiel von der deutschen VS.NET/Server Roadshow 2003
Enterprise Services Sample from the Slovenian NT Konferenca 2003, Norway Developer Days

Dieses Archiv beinhaltet das in meinem Enterprise Services Vortrag gezeigte Beispiel zu JustInTimeActivation und Pooling von der deutschen VS.NET/Windows Server 2003 Roadshow.

This sample around JustInTimeActivation and Pooling has also been shown at the DevDays in Norway last Tuesday and the NTKonferenca in Portoroz on Wednesday and is a slight variation of the DataSet caching example that I posted earlier.

Categories:

May 8, 2003
@ 10:07 PM

Sample code from Norway

Here's the zipped up sample code that I've been showing during my Metadata talk at the VS.NET launch event in Oslo. It's demonstrating yet another use of the constraint attributes that I've written quite a while ago. The idea is simple. When you use restriction facets on types defined in XSD and map them into a programming model, most of the facets get crippled away. They get totally lost when XSD.EXE generates classes and only length constraints survive DataSet code generation. Now, if you use the code in this archive, you can retrofit your classes with the appropriate facets like this:

 [System.Xml.Serialization.XmlTypeAttribute(
    Namespace="urn:schemas-newtelligence-com:
    transactionsamples:customerdata:v1")]
 public class customerType 
 {
  [Match(@"\p{L}[\p{L}\p{P}0-9\s]+"),MaxLength(80)]
  public string FirstName;
        
  [Match(@"\p{L}[\p{L}\p{P}0-9\s]+"),MaxLength(80)]
  public string LastName;
        
  [Match(@"[0-9\+][0-9\-\(\)\s]*"),MaxLength(26)]
  public string HomePhone;
        
  [Match(@"[0-9\+][0-9\-\(\)\s]*"),MaxLength(26)]
  public string BusinessPhone;
        
  [Match(@"[0-9\+][0-9\-\(\)\s]*"),MaxLength(26)]
  public string MobilePhone;
 }

.. and then you simply run an entire object graph through the validation function provided by the ConstraintValidator class like this:

ConstraintValidator cv = new ConstraintValidator();
cv.Validate( customers );

If validation fails, you get an exception with a detailed description of the problem. The net result is that all validation happens on the object graph and not using a serialization step and a run through the XmlValidatingReader. That saves time and allows you to keep promises in regards to XSD based message contracts even if your data will never be serialized into angle brackets. XSD rocks. Consider queued components. Voilá.

Update: I got an email comment detailing an (obviously pretty stupid) bug that I have in the validation function. I'll take a look at it and will post an update shortly. Fixed.

Categories:

Norwegian Visual Studio .NET 2003 launch event

I am on Norway today and I am sitting here blogging between two talks. "Say what you will say and listen to what you will listen to" was the first and now it's about Enterprise Services. It's going to take a day or two to wrap up the samples.

Categories:

The final version of Steve's and my slides from the "Scalable Applications" tour is now available at www.thearchitectexchange.com. -- including all changes and tweaks that we put in during the tour. We're very happy with that content as it is now. Requests for re-runs at an event location near your house are accepted here ;)

Categories:

Roy Osherove writes about typed DataSets and appropriate use. I would take it even a bit further.

If you look at them closely, DataSets are nothing more than a relational programming model for the XML Infoset. The DOM is a hierarchical programming model for the Infoset. XML Serialization is an object-typed programming model for the Infoset. Typed DataSets is a schema-bound programming model for Infoset and with that its really a relational programming model to PSVI. Still, it's a programming model for Infoset and I would argue that sharing programming models (or forcing programming models upon others) across boundaries isn't a good thing. Sharing serialized Infosets (one way to do so happens to be called "XML 1.0") is a Good Thing.

Update: Read the comments.

Categories:

In the presence of significant latency or significant work to guard boundaries, throughput (read: appropriate architecture) matters, not performance (read: spending a week to shave off 50 CPU cycles).  
Categories:

Don asks what I think about mixing code and data "at storage" inside a database. I simply call that a "data service". I'll give you the long answer:

The "layers and tiers" story that we presented at our tour is very simple. Everything you can talk to has layers: a public interface, an internal implementation and services and resource access hidden inside the internal implementation. It starts as simple as this:

public class MyService : IMyService
{
    // from IMyService 
    public int MyMethod(SomeData data) 
    { 
        return InternalMyMethod(); 
    }

    protected int InternalMyMethod(SomeData data)
    {
         MyBackend backend = new MyBackend();
         // do something with data
         backend.SomeMethod(data);
         return 0;

    }
}

I can add any number of variations of similar interfaces to that class without having to rewrite my internal implementation allowing for flexible binding of public interfaces to my implementation. Whenever I go outside the class I am using an external service or resource that I am often rather tightly bound to. I can go through a factory, but in the end I need to call a method or create a certain message. This basic principle remains true as you look at code from higher and higher up:

public class MyWebService : WebService
{
    [WebMethod]
    public int MyWebMethod(SomeData data) 
    { 
        return InternalMyWebMethod(data); 
    }
   
    [WebMethod]
    public int MyLiberalWebMethod(XmlElement any) 
    { 
        // try to map XML to SomeData here
        return InternalMyWebMethod(data); 
    }

    protected int InternalMyWebMethod(SomeData data)
    {
         // the "service access" layer is the proxy-portion of MyService().
         MyService backend = new MyService();
         // do something with data
         backend.MyMethod(data);
         return 0;

    }
}

Now we have a web service that uses the above class as its backend service. (When you leave the triplet of layers you are hitting a tier boundary, by the way). MyWebService, implementing an endpoint appropriate for "far" scenarios, as a whole is the public interface for our internal implementation MyService.

[Note: "Far" is not only strictly geographical, but also related to platform, trust, organization and other hurdles]

public class MyRPCService : ServicedComponent
{
    public int MyRPCMethod(SomeData data) 
    { 
        return InternalMyRPCMethod(data); 
    }
    
    protected int InternalMyRPCMethod(SomeData data)
    {
         MyService backend = new MyService();
         // do something with data
         backend.MyMethod(data);
         return 0;
    }
}

If can have any number of public interfaces for my internal implementation. Now I also have an RPC service with appropriate infrastructure for "near" scenarios (ServicedComponent) for the same internal implementation. Any service that deals with data can serve as an external service or resource manager for any other service. Layers are a recursive thing.

Any service provides appropriate functionality for its context. A web service front deals with all matters that have to do with mapping data from and to XML representations of data within the limits of its contract and leaves all other work to a backend service that serves as internal implementation. Another web service, possibly using the same backend is again scoped in functionality by its contract. A web form application deals with rendering data into HTML and handling interactive events and, again, leaves the actual work to its backend. There is very few appropriate code that might be useful in multiple contexts.

Now back to Don's question:

Sure it's appropriate to have data and code mixed in the database. The public interface implementation tools for a database are called "stored procedure" and "view". The internal implementation tools are called "table", "index" and "view". The service and resource access interface is called SQL. A database is just another layered service. When I have a proper public interface to submit my data to or initiate operations on and if the internal implementation is appropriately hidden from me, it doesn't matter how the database is implemented. The database gods can throw indexes and tables around as they wish and they can make it look for me as if nothing ever changed -- if it is an OODBMS that's just fine, too. The OODB "objects" in the database just can't "leave the database" and can't implement functionality that is not immediately appropriate for the context they're in. Storing instances of a class that has methods knowing how to render its data onto spinning cube using Direct3D isn't appropriate; storing an instance of a class that has methods that implement functions to transition between two consecutive consistent states are appropriate. Any use of these methods outside the database is inappropriate again.

Of course, what one wants to do in the bigger picture is to have a proper data service on the client side, whose internal implementation deals with client caching and techniques to eliminate/limit locking as appropriate the the character of data. With that, a "data service" consists of two sub-services. One service lives in the database, one service lives on the client and they have a tier boundary between them. Still, from the outside, the "data service" is a black box with a single public interface (the client's) that serves as an  implementation tool for the services and resource access for layers higher up.

Categories:

Putting code and data into a single thing is a bad idea for distributed systems. Behavior is bound to the role that data plays in a functional scope. Presentation is a scope, calculation, combination, aggregation and validation are scopes, services and resource access is a scope. Having all code for all scopes on a single thing is bad. "Technology choice" causes inability to share implementation across organization boundaries. Mobile devices and web services are both like the "big bang": things get further and further away from each other (in terms of geography, trust and organizational association), causing more inability to share implementation and causing behavior that's bound to data and is located at central places to be the mother of all bottlenecks and plenty of other problems for scenarios where the boundary between tiers may ever have such "far" characteristics. I leave the conclusions to the reader, but here's a hint: MarshalByRefObject

Categories:

First drop of samples from scalable apps tour.

Here are the samples that we ran (for the purpose of illustrating some points, not really to drill into these specific implementations) at the events in the past two weeks. These are not demos that illustrate scalability per-se. We couldn't carry enough laptops with us to illustrate scalability for real. These demos deal with transactions, layers and performance tuning. (Reminder: Performance has little to do with throughput -- think about all the time people spend in traffic jams with their Porsche 911 running in idle).

Categories:

newtelligence SDK for Enterprise Services 2.0 RC1

The newtelligence SDK for Enterprise Services is a set of classes and infrastructure extensions for the System.EnterpriseServices programming model to Windows Enterprise Services (COM+) in the Microsoft Windows .NET Framework. The extensions are designed to work with Windows Server 2003, Windows XP and Windows 2000.

The tools contained in this kit provide the following enhancements for Enterprise Services.

  • Custom interception extensibility for managed components (ServicedComponents) hosted in COM+ 1.0 and COM+ 1.5.
        (AspectServicedComponent class and utilities)
  • Windows installer support
        (EnterpriseServicesApplicationInstaller class)
  • Shared, context-scoped state using custom context properties
        (ContextUtilEx class)
  • The ability to create serviced components in non-default application domains
        (ApplicationDomainAttribute class and ServicedComponentEx class)
  • Inline transaction support using "services without components" also on Windows XP 
        (InlineTransaction class)
  • Just-in-time activation proxy pooling
        (JITAPool class)
  • Managed wrappers for the configuration catalog
       (CatalogManager and related classes)

Requirements:

  • Microsoft Visual Studio .NET 2003
  • .NET Framework 1.1
  • Microsoft Windows Server 2003 (recommended) or
  • Microsoft Windows XP or
  • Microsoft Windows 2000 Server/Professional

The full reference documentation and samples are available inside Visual Studio .NET 2003 after installing the SDK.

We still do not plan to charge license fees for the binaries when we move them to "release" status, but we cannot and will not offer any reliable support on "free" terms, of course.

 

Categories:

A simple in memory cache for "business data"

Here is a little project demonstrating a little in-memory data cache using DataSets and serviced components. The demo illustrates how to deal with near data in a smarter way than by just walking up to SQL Server all the time. My "Layers and Tiers" slide deck of the recent tour makes the point that it's a good idea to delegate data access to services which are aware of the temporal character of data (static, near static, dynamic and "hot") and optimize access to that data accordingly. The sample also illustrates a way of implementing proper layering for such a data service: The public interface is a Serviced Components (an alternate public interface could be a web service or whatever else), the internal implementation is a base class providing the caching logic and the resource access is realized by deriving one version for SQL Server access and one of OleDb access from this base class. Creating instances of the concrete implementations is done through a config-driven factory.  -- looser binding towards the "client edge" and tighter binding towards the "backend edge".

The concrete implementation assumes that the "Products" and "Categories" tables in the accessed Northwind database copy are in a read-only replica and assumes that the data will always conveniently fit into memory. The demo shows the perf. difference between the cached and the direct database access versions.

The time difference isn't only due to the caching, though. The sample also shows how to use "connection pooling" to JITA Enterprise Service components using a client side JITA pool. The code for that is included.

Categories:

May 3, 2003
@ 05:11 AM

Thank you, Steve :) 

Yesterday, in Portugal, was the last stop on the "Scalable Applications Tour". And I consider this one more significant than any event I've done before. Why?

  • This was the only event series I know of where an external, "regular guy" like me and senior architect form a Microsoft product group have been together on a speaking tour of this scale. 
  • This was the only event series I know of where Enterprise Services and ASP.NET Web Services got an even-handed coverage in term of features and use-cases. The wwinning combination is to use both. 
  • This was the only event series I know of where Windows product features introduced in 1997 got even-handed coverage with Windows product features introduced in 2003. The goal was to paint the big picture and not to give the usual, incremental "here's something new" talks.

It was a lot of fun. I learned a lot, Steve says that he learned a lot and I am sure that the 2200+ people we could do these talks for were also able to take some valuable information home.

Notice to attendees: All sample code and the final set of slides will be available within the next 24-72 hours for download. Watch this space for a pointer to the download location(s).

Categories:

Scalable Applications Tour update

All the travel this week (Oslo, Copenhagen, Paris, Lisbon) has definitely taken its toll on Steve's and my ability to communicate with the outside world, including blogging and posting updates to the slides and the sample code. However, the whole tour is great fun and we've made some great improvements on our content and the "overall experience". We'll have the final slides up at www.thearchitectexchange.com by Saturday and I will spend some time tomorrow to wrap up all samples into a single zip archive that I'll post there as well.

Categories: