The flow of the talk was (Term-Definition-Haiku-XML-code)+. Here's the basic content formatted fairly hastily for this blog entry:
Message
Noun, An XML-compatible unit of information exchanged by programs
Message, oh Message
The Truth Is On The Wire
There Is Nothing Else
static void Main() { // mysvc
Message request = Message.CreateMessage(XmlReader.Create(Console.In));
Message reply = null;
Console.WriteLine(request.Headers.Action);
if (request.Headers.Action == "http://schemas.microsoft.com/demos/ListProcesses")
{
var query =
new XElement("Processes",
from p in Process.GetProcesses()
select new XElement("ProcessData",
new XElement("Name", p.ProcessName),
new XElement("WorkingSet", p.WorkingSet)));
reply = Message.CreateMessage(
request.Version,
"http://schemas.microsoft.com/demos/ProcessListing",
new XBodyWriter(query));
}
else
{
reply = Message.CreateMessage(
request.Version,
MessageFault.CreateFault(
new FaultCode("InvalidAction"),
new FaultReason( string.Format("Action {0} not recoginized", request.Headers.Action))
)
);
}
reply.WriteTo(new XmlTextWriter(Console.Out));
}
Contract
Noun, An XML-compatible description of a set of message exchanges
To Marry Our Apps,
Your Contract Or My Contract?
Both Color The Dance…
name="ProcessData" nillable="true" type="ProcessData" />
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
</wsdl:types>
<wsdl:message name="ListProcessesMessage" />
<wsdl:message name="ProcessListingMessage">
<wsdl:part name="Processes" element="Processes" />
</wsdl:message>
<wsdl:portType name="ProcessManagementContract">
<wsdl:operation name="GetProcesses">
<wsdl:input wsa:Action="http://schemas.microsoft.com/demos/ListProcesses" message="tns:ListProcessesMessage" />
<wsdl:output wsa:Action="http://schemas.microsoft.com/demos/ProcessListing" message="tns:ProcessListingMessage" />
</wsdl:operation>
</wsdl:portType>
</wsdl:definitions>
static void Main() { // requestgen
ListProcessesMessage request = new ListProcessesMessage();
Message msg = TypedMessageConverter.ToMessage(request);
msg.WriteTo(new XmlTextWriter(Console.Out));
}
static void Main() { // replysync
Message msg = Message.CreateMessage(XmlReader.Create(Console.In));
ProcessListingMessage reply = TypedMessageConverter.FromMessage<ProcessListingMessage>(msg);
foreach (ProcessData proc in reply.Processes)
Console.WriteLine("{0,-30}{1}", proc.Name, proc.WorkingSet);
}
; poor-man's orchestration langauge
C:\demodir> requestgen | mysvc | replysync
Service
Noun, A collection of XML-compatible named messaging endpoints
An Endpoint Per Chance,
Address, Binding, and Contract,
That Is What Matters!
</service>
</services>
<client>
<endpoint
configurationName="myEndpoint"
contract="ProcessManagementContract"
binding="wsHttpBinding"
address="http://localhost/myPath/ws"
/> </client>
</system.serviceModel>
</configuration>
// the client program that uses asynchronous passing of statically typed messages
static void Main(string[] args)
{
ListProcessesMessage request = new ListProcessesMessage();
ProcessManagementContract channel =
ChannelFactory.CreateChannel<ProcessManagementContract>(
"myEndpoint");
IAsyncResult result = channel.BeginGetProcesses(request, null, null);
while (!result.IsCompleted)
{
Console.WriteLine("waiting ...");
System.Threading.Thread.Sleep(500);
}
ProcessListingMessage reply = channel.EndGetProcesses(result);
foreach (ProcessData p in reply.Processes)
{
Console.WriteLine("{0,-30}{1,10}", p.Name, p.WorkingSet);
}
}
// the "universal" contract used by the service to allow any message to arrive
[ServiceContract]
public interface UniversalContract
{
[OperationContract(Action = "*", ReplyAction = "*")]
Message HandleMessage(Message request);
}
// our service implementation that parrots the Console.In|Out program from "Message"
public class ProcessManagementService : UniversalContract
{
public Message HandleMessage(Message request)
{
Message reply = null;
if (request.Headers.Action == "http://schemas.microsoft.com/demos/ListProcesses")
{
var query =
new XElement("Processes",
from p in Process.GetProcesses()
select new XElement("ProcessData",
new XElement("Name", p.ProcessName),
new XElement("WorkingSet", p.WorkingSet)));
reply = Message.CreateMessage(
request.Version,
"http://schemas.microsoft.com/demos/ProcessListing",
new XBodyWriter(query));
}
else
{
reply = Message.CreateMessage(
request.Version,
MessageFault.CreateFault(
new FaultCode("InvalidAction"),
new FaultReason(string.Format("Action {0} not recoginized", request.Headers.Action))
)
);
}
return reply;
}
}
// the hosting code for our service
static void Main(string[] args)
{
ServiceHost host = new ServiceHost(typeof(ProcessManagementService));
host.Open();
foreach (EndpointListener listener in host.EndpointListeners)
Console.WriteLine(listener.Listener.LocalAddress);
Console.WriteLine("Service Started!");
Console.ReadLine();
host.Close();
}
Claim
Noun, An XML-compatible assertion that helps establish a digital identity
“I’m Me,” I Assert!
And If You Don’t Believe Me,
Trust The Issuer!
<SEC:Security>... Gudginesque XML goes here ...</SEC:Security>
</S:Header>
<S:Body />
</S:Envelope>
if (OperationContext.Current.ServiceSecurityContext != null)
{
foreach (ClaimSet cs in OperationContext.Current.ServiceSecurityContext.AuthorizationContext)
{
foreach (Claim claim in cs)
{
Console.WriteLine(claim);
}
}
}
Workflow
Noun, An XML-compatible program that combines domain-specific activities
A XAML Runtime:
Now You Too Can Be Chris Brumme;
Is It Possible?
// myapp.xaml
<?Mapping XmlNamespace="http://schemas.microsoft.com/winfx/2005/workflow/activities"
ClrNamespace="System.Workflow.Activities"
Assembly="System.Workflow.Activities" ?>
<?Mapping ClrNamespace="PDC" Assembly="WriteLine" XmlNamespace="http://fabrikam.com/domainstuff" ?>
<SequentialWorkflow
xmlns:wl="http://fabrikam.com/domainstuff"
xmlns:x="Definition"
ID="wf"
x:Class="MyApplication"
xmlns="http://schemas.microsoft.com/winfx/2005/workflow/activities"
>
<Parallel ID="xxxx">
<Sequence ID="UUUUU" >
<Delay TimeoutDuration="00:00:05" ID="xx7" />
<wl:WriteLine Text="One" ID="xx1" />
<wl:WriteLine Text="Two" ID="xx2" />
<wl:WriteLine Text="Three" ID="xx3" />
</Sequence>
<Sequence ID="UUUUUUUUUUUUUU" >
<wl:WriteLine Text="Four" ID="xx4" />
<wl:WriteLine Text="Five" ID="xx5" />
</Sequence>
</Parallel>
</SequentialWorkflow>
// myactivity.cs
using System;
using System.Workflow.ComponentModel;
namespace PDC {
public class WriteLine : Activity {
string text;
public string Text {
get { return text; }
set { text = value; }
}
protected override Status Execute(ActivityExecutionContext aec) {
// enterprise-ready business logic goes here...
Console.WriteLine("Contoso-Fabrikam: {0}", text);
return Status.Closed;
}
}
}
// shell hosting program
using System;
using System.Collections.Generic;
using System.Text;
using System.Reflection;
using System.Workflow.ComponentModel.Compiler;
using System.Workflow.ComponentModel;
using System.Workflow.Runtime;
using System.Workflow.Runtime.Hosting;
namespace XomlShell {
class Program {
static void Main(string[] args) {
string xomlPath = args[0];
string[] refs = new string[args.Length - 1];
Array.Copy(args, 1, refs, 0, refs.Length);
WorkflowCompilerParameters p = new WorkflowCompilerParameters(refs);
p.GenerateInMemory = true;
WorkflowCompilerResults results = new WorkflowCompiler().CompileFromFile(p, xomlPath);
if (results.Errors.HasErrors) {
foreach (object error in results.Errors)
Console.WriteLine(error);
}
else {
Assembly assm = results.CompiledAssembly;
AppDomain.CurrentDomain.AssemblyResolve += delegate(object sender, ResolveEventArgs e) {
if (e.Name == assm.GetName().ToString())
return assm;
return null;
};
Type workflowType = null;
foreach (Type type in assm.GetTypes())
if (typeof(IRootActivity).IsAssignableFrom(type)) {
workflowType = type;
break;
}
WorkflowRuntime runtime = new WorkflowRuntime();
runtime.StartRuntime();
System.Threading.ManualResetEvent ev = new System.Threading.ManualResetEvent(false);
runtime.WorkflowCompleted += delegate(object s, WorkflowCompletedEventArgs eee) {
ev.Set();
};
WorkflowInstance instance = runtime.StartWorkflow(workflowType);
ev.WaitOne();
}
}
}
}
Future
Noun, An XML-compatible world that supports collaboration between programmers and civilians
Code Versus Data?
Is That Really The Question?
Both Must Coexist…
Posted
Sep 22 2005, 07:01 PM
by
don-box