Design Patterns, Practices, and Techniques
with the Azure AppFabric Service Bus
Juval Lowy
IDesign
www.idesign.net
©2011 IDesign Inc. All rights reserved
About Juval Löwy
Software architect
Consults and trains on .NET architecture and technology
Microsoft's Regional Director for the Silicon Valley
Recent book
Programming WCF Services 3rd Edition (2010 O’Reilly)
Participates in the .NET/WCF design reviews
Publishes at MSDN and other magazines
Recognized Software Legend by Microsoft
Contact at www.idesign.net
Agenda
What is the service bus
Brief
Techniques
Publishing to registry
Discrete events
Discovery
Explorer
Structured buffers
Response service
Bonus Material
Time permitting
Azure AppFabric Service Bus
While designed to address connectivity issues also provides
Scalability
Availability
Security
Lower technology entrance barrier by making advanced scenario
main-stream and mundane
Why Service Bus
Internet connectivity is hard
Firewalls
Load balancers
Sessions
NAT
Private IPs
Discovery and registry
Virtualization
Proxy servers
LB
NAT
Router
H/W Firewall
S/W Firewall
Client
Service
Security
IT in general
…
Why Service Bus
Scalability throughput and availability challenges
Opening your Intranet
Requires DMZ
Clients credentials management
Commonplace solutions
Cumbersome
Not real-time
Potentially insecure
Why Service Bus
Solution
Do not connect clients to services directly
At least not initially
Use a relay service
Relay service in the cloud
Neutral territory
Only requires outbound calls to establish connection
Allowed in most environments
Will relay client calls to service
Additional benefits of scalability, security, administration
Service Bus Relay
1. Service connects and authenticates against relay
Relay figures out how to best call back to service
2. Client connects and authenticates against relay
3. Client sends message to service
4. Relay forwards message to service
Relay
Service
2
3
Client
1
4
Service
Azure AppFabric Service Bus
Ready-made service bus relay service
DMZ in the sky
Only allows authenticated authorized calls
Repels attacks and hides service
Relay service in cloud routing messages
Microsoft massive data centers
Additional features
Security
Access rules
Service registry
Relay Service Address
Address format
[base address]/[optional URI]/.../[optional URI]
Bus address format
[schema]://[namespace].servicebus.windows.net/
Schema format is sb or http or https
Binding dependent
Services Registry
Can view ATOM feed of listening services in namespace
Or one of its sub URI
http://[namespace].servicebus.windows.net/[URI]
Services Registry
Can control publishing to registry
public enum DiscoveryType
{
Public,
Private
}
public class ServiceRegistrySettings : IEndpointBehavior
{
public ServiceRegistrySettings();
public ServiceRegistrySettings(DiscoveryType discoveryType);
public DiscoveryType DiscoveryMode
{get;set;}
public string DisplayName
{get;set;}
}
Services Registry
Must use programmatic setting
IEndpointBehavior registeryBehavior = new ServiceRegistrySettings(DiscoveryType.Public);
ServiceHost host = new ServiceHost(typeof(MyService));
foreach(ServiceEndpoint endpoint in host.Description.Endpoints)
{
endpoint.Behaviors.Add(registeryBehavior);
}
host.Open();
Discoverable Host
My DiscoverableServiceHost automates registry
Used like regular host
public class DiscoverableServiceHost : ServiceHost,IServiceBusProperties
{
public DiscoverableServiceHost(object singletonInstance,params Uri[] baseAddresses);
public DiscoverableServiceHost(Type serviceType,params Uri[] baseAddresses);
//More members
}
IServiceBusProperties
All my service bus helpers support my
IServiceBusProperties
public interface IServiceBusProperties
{
TransportClientEndpointBehavior Credential
{get;set;}
Uri[] Addresses
{get;}
}
Service Bus Explorer
View with my Service Bus Explorer
Can administer buffers as well
Service Bus Bindings
The three main bindings
NetTcpRelayBinding
NetOnewayRelayBinding
NetEventRelayBinding
TCP Relay Binding
Binding of choice in most cases
Best performance and throughput
Minimum overhead for service
Unlimited message size
Up to configured limits
Request-reply messages through relay
TCP Relay Binding
Multiple clients / single service
As with regular WCF
Maintains transport session
Clients gets the same instance
Not interoperable
Uses sb for transport
<endpoint
address = "sb://MyNamespace.servicebus.windows.net/..."
binding = "netTcpRelayBinding"
contract = "..."
/>
One-Way Relay Binding
No reply messages
All operations must be one-way
Message goes into a buffer
Messages limited to 64 KB
Used sb for scheme
<endpoint
address = "sb://MyNamespace.servicebus.windows.net/..."
binding = "netOnewayrelayBinding"
contract = "..."
/>
Event Relay Binding
Specialization of one-way relay
public class NetEventRelayBinding : NetOnewayRelayBinding
{...}
Allows any number of services to monitor buffer
N:M communication
Can safely listen concurrently on nested URIs
For whatever reason
Clients may still call over NetOnewayRelayBinding
Services must use NetEventRelayBinding
Service Bus as Events Hub
Publisher
Publisher
Events
Hub
Subscriber
Subscriber
Subscriber
Service Bus as Events Hub
Light weight pub/sub system
No administrative support
No per-operation subscription
Endpoint level only
Service Bus as Events Hub
Subscriber still receives events it may not care about
simply because it has a matching endpoint
[ServiceContract]
interface IMyEvents
{
[OperationContract(IsOneWay = true)]
void OnEvent1();
[OperationContract(IsOneWay = true)]
void OnEvent2(int number);
[OperationContract(IsOneWay = true)]
void OnEvent3(int number,string text);
}
Service Bus as Events Hub
To manage events at the operation level need to map
URIs to operations not endpoints
<endpoint name = "OnEvent1"
address = "sb://MyNamespace.servicebus.windows.net/IMyEvents/OnEvent1"
binding = "netOnewayBinding"
contract = "IMyEvents"
/>
<endpoint name = "OnEvent2"
address = "sb://MyNamespace.servicebus.windows.net/IMyEvents/OnEvent2"
binding = "netOnewayBinding"
contract = "IMyEvents"
/>
<endpoint name = "OnEvent3"
address = "sb://MyNamespace.servicebus.windows.net/IMyEvents/OnEvent3"
binding = "netOnewayBinding"
contract = "IMyEvents"
/>
Service Bus as Events Hub
Have as many hosts as subscribed operations all targeting
same service type
At run-time must recycle hosts and programmatically add each
desired endpoint to specific host
Tedious repetitive code
Expensive
Pay for connections
Service Bus as Events Hub
Streamline with my ServiceBusEventsHost
public class ServiceBusEventsHost : DiscoverableServiceHost
{
public ServiceBusEventsHost(Type serviceType,Uri baseAddress);
public ServiceBusEventsHost(Type serviceType,Uri[] baseAddresses);
/*Additional constructors */
//Can optionally specify binding
public virtual NetOnewayRelayBinding RelayBinding
{get;set;}
public void SetBinding(string bindingConfigName);
//Subscription management
public void Subscribe();
public void Subscribe(Type contractType);
public void Subscribe(Type contractType,string operation);
public void Unsubscribe();
public void Unsubscribe(Type contractType);
public void Unsubscribe(Type contractType,string operation);
}
Service Bus as Events Hub
ServiceBusEventsHost used like regular host
Requires base address(es)
Appends contract name to each base address
Can accept binding to use
Defaults for secure binding
No need for config file
Can look up binding from config
Can subscribe or unsubscribe all operations on all contracts
Can subscribe or unsubscribe all operations on contract
Can subscribe or unsubscribe specific operation on contract
[ServiceContract]
interface IMyEvents
{
[OperationContract(IsOneWay = true)]
void OnEvent1();
[OperationContract(IsOneWay = true)]
void OnEvent2(int number);
[OperationContract(IsOneWay = true)]
void OnEvent3(int number,string text);
}
class MySubscriber: IMyEvents
{...}
string baseAddress = "sb://MyNamespace.servicebus.windows.net/";
ServiceBusEventsHost host = new ServiceBusEventsHost(typeof(MySubscriber),baseAddress);
host.Open();
host.Subscribe();
host.Unsubscribe(typeof(IMyEvents),"OnEvent2");
host.Subscribe();
host.Unsubscribe();
Service Bus as Events Hub
Subscriptions stored in dictionary
Maps subscribed operations per contract
Can add admin support
Use a tool to manage subscriptions outside scope of host/service
Manage subscriptions against host as needed
Service Bus as Events Hub
ServiceBusEventsHost adds endpoint
per base address per contract
[base address]/[contract name]
Monitors all messages to that address and below
Publishers send messages to endpoint whose address
contains operation name
[base address]/[contract name]/[operation]
Service Bus as Events Hub
ServiceBusEventsHost uses operation selector
interceptor to rout message to subscribed operation
Attached as endpoint behavior to all dispatchers
public interface IDispatchOperationSelector
{
string SelectOperation(ref Message message);
}
//Partial listing without error handling
public class ServiceBusEventsHost : ServiceBusHost
{
//Managing the subscriptions
Dictionary<string,List<string>> Subscriptions
{get;set;}
public ServiceBusEventsHost(Type serviceType,Uri[] baseAddresses) :
base(serviceType,baseAddresses)
{
Subscriptions = new Dictionary<string,List<string>>();
foreach(Uri baseAddress in BaseAddresses)
{
Type[] contracts = GetServiceContracts();
foreach(Type contract in contracts)
{
AddServiceEndpoint(contract,RelayBinding,
baseAddress.AbsoluteUri + contract);
Subscriptions[contract.Name] = new List<string>();
}
}
IEndpointBehavior selector = new EventSelector(Subscriptions);
foreach(ServiceEndpoint endpoint in Description.Endpoints)
{
endpoint.Behaviors.Add(selector);
}
}
public void Subscribe(Type contractType,string operation)
{
if(Subscriptions[contractType.Name].Contains(operation) == false)
{
Subscriptions[contractType.Name].Add(operation);
}
}
public void Unsubscribe(Type contractType,string operation)
{
if(Subscriptions[contractType.Name].Contains(operation))
{
Subscriptions[contractType.Name].Remove(operation);
}
}
//Uses reflection to get all service contracts
Type[] GetServiceContracts()
{...}
class EventSelector : IDispatchOperationSelector,IEndpointBehavior
{
readonly Dictionary<string,List<string>> m_Subscriptions;
public EventSelector(Dictionary<string,List<string>> subscriptions)
{
m_Subscriptions = subscriptions;
}
public string SelectOperation(ref Message message)
{
string[] slashes = message.Headers.Action.Split('/');
string contract = slashes[slashes.Length-2];
string operation = slashes[slashes.Length-1];
if(m_Subscriptions[contract].Contains(operation))
return operation;
else
return null;
}
void IEndpointBehavior.ApplyDispatchBehavior(
ServiceEndpoint endpoint,EndpointDispatcher endpointDispatcher)
{
endpointDispatcher.DispatchRuntime.OperationSelector = this;
}
...
}
}
Service Bus as Events Hub
Publisher can use plain one-way relay proxy
Careful to match expected endpoints layout
Automate proxy with my ServiceBusEventsClientBase
Appends contract name and operation to base address
No need for config file
Only needs base address
Always uses one way relay binding
Used like regular proxy
public abstract class ServiceBusEventsClientBase<T> : ...ClientBase<T> where T : class
{
public ServiceBusEventsClientBase(string baseAddress) :
this(baseAddress,new NetOnewayRelayBinding())
{}
public ServiceBusEventsClientBase(string baseAddress,NetOnewayRelayBinding binding) :
base(binding,ToEventAddress(baseAddress))
{}
/* More constructors */
static EndpointAddress ToEventAddress(string baseAddress)
{
return new EndpointAddress(baseAddress + typeof(T).Name);
}
}
Service Bus as Events Hub
class MyEventsProxy : ServiceBusEventsClientBase<IMyEvents>,IMyEvents
{
public MyEventsProxy(string baseAddress) : base(baseAddress)
{}
public void OnEvent1()
{
Channel.OnEvent1();
}
public void OnEvent2(int number)
{
Channel.OnEvent2(number);
}
public void OnEvent3(int number,string text)
{
Channel.OnEvent3(number,text);
}
}
Discovery
Discovery
Discovery was designed for the Intranet
Discovery is useful
Loosely-coupled clients and services
Dynamic addresses
Easy deployment
Service bus may support discovery in future
Discovery
Would be nice to combine benefit of loose deployment of
discovery with unhindered connectivity of service bus
Can substitute events binding for UDP
Discovery requests
Announcements
Mimic WCF discovery behavior
Solution Architecture
Streamline with my helpers
IServiceBusDiscovery for discovery requests
Events relay binding
Supported by discoverable services
Provides reply address of client
[ServiceContract]
public interface IServiceBusDiscovery
{
[OperationContract(IsOneWay = true)]
void DiscoveryRequest(string contractName,string contractNamespace,
Uri[] scopesToMatch,Uri responseAddress);
}
Solution Architecture
IServiceBusDiscoveryCallback for receiving
services responses
Exposed by clients
Over one-way relay binding
[ServiceContract]
public interface IServiceBusDiscoveryCallback
{
[OperationContract(IsOneWay = true)]
void DiscoveryResponse(Uri address,string contractName,string contractNamespace,
Uri[] scopes);
}
Client
Operation
Event
3
1
IServiceBusDiscovery
Discovery
Requests
Relay
Service
Relay
Service
IServiceBusDiscoveryCallback
2
Service
Discoverable Host
My DiscoverableServiceHost
Used like regular host
To enable must add discovery behavior and discovery endpoint
Forward looking and compatible
Discoverable Host
public class DiscoverableServiceHost : ServiceHost,IServiceBusProperties
{
public Uri DiscoveryAddress
{get;set;}
public NetEventRelayBinding DiscoveryRequestBinding
{get;set;}
public NetOnewayRelayBinding DiscoveryResponseBinding
{get;set;}
public DiscoverableServiceHost(object singletonInstance,params Uri[] baseAddresses);
public DiscoverableServiceHost(Type serviceType,params Uri[] baseAddresses);
}
Discoverable Host
Creates internal host for private service class
DiscoveryRequestService implementing
IServiceBusDiscovery
Monitors discovery requests
Address defaults to URI "DiscoveryRequests"
Configurable via DiscoveryAddress property
Uses plain events binding to receive requests
Configurable via DiscoveryRequestBinding property
Calls back client using IServiceBusDiscoveryCallback
Uses plain one way binding
Configurable via DiscoveryResponseBinding property
Discoverable Host
Uri baseAddress = new Uri("sb://...");
ServiceHost host = new DiscoverableServiceHost(typeof(MyService,baseAddress);
//Address is dynamic
host.AddServiceEndpoint(typeof(IMyContract),new NetTcpRelayBinding(),
Guid.NewGuid().ToString());
host.Open();
Discovery Client
For client use my ServiceBusDiscoveryClient
Modeled after DiscoveryClient
public class ServiceBusDiscoveryClient : ClientBase<IServiceBusDiscovery>,
IServiceBusProperties
{
protected Uri ResponseAddress
{get;}
public ServiceBusDiscoveryClient(string serviceNamespace,...);
public ServiceBusDiscoveryClient(string endpointName);
public ServiceBusDiscoveryClient(NetOnewayRelayBinding binding,EndpointAddress address
public FindResponse Find(FindCriteria criteria);
}
Discovery Client
ServiceBusDiscoveryClient is proxy for
IServiceBusDiscovery
Defaults address to URI "DiscoveryRequests"
Can provide constructors with different address
Uses plain one-way binding to fire requests and receive
responses
Can provide constructors with different binding
Supports cardinality and timeouts
Find() hosts an internal service supporting
IServiceBusDiscoveryCallback
Opens and closes host per call
Discovery Client
string serviceNamespace = "...";
ServiceBusDiscoveryClient discoveryClient =
new ServiceBusDiscoveryClient(serviceNamespace,...);
FindCriteria criteria = new FindCriteria(typeof(IMyContract));
FindResponse discovered = discoveryClient.Find(criteria);
discoveryClient.Close();
EndpointAddress address = discovered.Endpoints[0].Address;
Binding binding = new NetTcpRelayBinding();
ChannelFactory<IMyContract> factory = new ChannelFactory<IMyContract>
(binding,address);
IMyContract proxy = factory.CreateChannel();
proxy.MyMethod();
(proxy as ICommunicationObject).Close();
Service Bus Discovery Helper
Helper class
public static class ServiceBusDiscoveryHelper
{
public static EndpointAddress DiscoverAddress<T>(
string serviceNamespace,...,Uri scope = null);
public static EndpointAddress[] DiscoverAddresses<T>(
string serviceNamespace,...,Uri scope = null);
public static Binding DiscoverBinding<T>(
string serviceNamespace,...,Uri scope = null);
}
Service Bus Discovery Factory
Helper factory
public static class ServiceBusDiscoveryFactory
{
public static T CreateChannel<T>(string serviceNamespace,...,Uri scope = null)
where T : class;
public static T[] CreateChannels<T>(string serviceNamespace,...,Uri scope = null)
where T : class;
}
Announcements
Can use events binding to support announcements
My IServiceBusAnnouncements
[ServiceContract]
public interface IServiceBusAnnouncements
{
[OperationContract(IsOneWay = true)]
void OnHello(Uri address,string contractName,string contractNamespace,Uri[] scopes);
[OperationContract(IsOneWay = true)]
void OnBye(Uri address,string contractName,string contractNamespace,Uri[] scopes);
}
Client
Operation
Event
2
Announcements
Relay
Service
IServiceBusAnnouncements
1
Service
Announcements
Automated with DiscoverableServiceHost
public class DiscoverableServiceHost : ServiceHost,IServiceBusProperties
{
public Uri AnnouncementsAddress
{get;set;}
public NetOnewayRelayBinding AnnouncementsBinding
{get;set;}
//More members
}
Announcements
Requires configuring announcements endpoint in
discovery behavior
Defaults to announcing on "AvailabilityAnnouncements"
URI under service namespace
Configurable via AnnouncementsAddress property
Calls client using plain one way binding
Configurable via AnnouncementsBinding property
Fires event asynchronously
Announcements
Client uses my ServiceBusAnnouncementSink<T>
[ServiceBehavior(UseSynchronizationContext = false,
InstanceContextMode = InstanceContextMode.Single)]
public class ServiceBusAnnouncementSink<T> : AnnouncementSink<T>,IServiceBusAnnouncements
,IServiceBusProperties where T : class
{
public ServiceBusAnnouncementSink(string serviceNamespace,string secret);
public ServiceBusAnnouncementSink(string serviceNamespace,string owner,string secret);
public Uri AnnouncementsAddress
{get;set;}
public NetEventRelayBinding AnnouncementsBinding
{get;set;}
}
Announcements
Supports IServiceBusAnnouncements
Hosted as singleton published to registry
Subscribes to events
Defaults to "AvailabilityAnnouncements" URI
Configurable via AnnouncementsAddress property
Uses plain events binding
Configurable via AnnouncementsBinding property
Client can subscribe to events or access addresses
container
class MyClient
{
AddressesContainer<IMyContract> m_Addresses;
public MyClient()
{
string serviceNamespace = "...";
string secret = "...";
m_Addresses = new ServiceBusAnnouncementSink<IMyContract>(serviceNamespace,secret);
m_AnnouncementSink.Open();
...
}
void OnCallService(object sender,EventArgs e)
{
EndpointAddress address = m_Addresses[0];
IMyContract proxy = ChannelFactory<IMyContract>.CreateChannel(
new NetTcpRelayBinding(),address);
proxy.MyMethod();
(proxy as ICommunicationObject).Close();
}
...
MEX Explorer
Revamped to use service bus discovery and
announcements
Buffers
Service Bus Buffers
Queued calls over the Internet
Almost
Every junction in the service bus can host a buffer
Sender
Reader
Service Bus Buffers
Buffer does not equate queue
Not durable
Data loss with catastrophic crash of service bus
Not transactional
Not long lasting messages
Max is 10 minutes
Buffers are limited
Up to 50 messages
In between queued calls and fire-and-forget calls
Service Bus Buffers
Aimed at
Async calls
Chunky calls
Mostly connected applications on somewhat shaky connections
One-way calls
Elastic Internet wire
Service Bus Buffers
All messages are one-way
No results
No errors
No callbacks
Service Bus Buffers
Can manage and create buffers with the my Explorer
Service Bus Buffers
Can manage and create buffers with my Explorer
Buffered Services
The service bus requires working with raw WCF messages
Raw messages are
Cumbersome
Not object-oriented
Not type safe
Should convert between service calls and raw messages
Requires a lot of low level advanced work
Buffered Services
Automate with my BufferedServiceBusHost<T>
Used like a regular host
Modeled after MSMQ binding
public class BufferedServiceBusHost<T> : ServiceHost<T>,...
{
public BufferedServiceBusHost(params Uri[] bufferAddresses);
public BufferedServiceBusHost(T singleton,params Uri[] bufferAddresses);
/* Additional constructors */
}
Uri buffer = new Uri(@"https://MyNamespace.servicebus.windows.net/MyBuffer");
ServiceHost host = new BufferedServiceBusHost<MyService>(buffer);
host.Open();
Buffered Services
For client use BufferedServiceBusClient<T>
[ServiceContract]
interface IMyContract
{
[OperationContract(IsOneWay = true)]
void MyMethod(int number);
}
class MyContractClient : BufferedServiceBusClient<IMyContract>,IMyContract
{
public void MyMethod(int number)
{
...
}
}
Response Service
No way to get
Results
Errors
Client can provide dedicated response buffer for service
Should pass response address and method ID in headers
Automate with my framework
Response Service
Service Buffer
Client
Service
Response Buffer
Response
Service
Bonus Material
Service Bus Security
Security Aspects
Service bus authentication
Message transfer security
Service Bus Authentication
Service must authenticate to connect to service bus
Client may or may not authenticate
Typically should
Application authentication
Not user authentication
Service Bus Authentication
Administrator uses portal to assign and create tokens
Service Bus Authentication
Tokens both authenticate and authorize
Sending messages
Reading messages
Manage service namespace
Service and client may not use the same token
Service Bus Authentication
Can streamline with my extension method
Defaults to owner as issuer
public static class ServiceBusHelper
{
public static void SetServiceBusCredentials(this ServiceHost host,string secret);
...
}
ServiceHost host = new ServiceHost(typeof(MyService));
host.SetServiceBusCredentials("QV3...9M8=");
host.Open();
Service Bus Authentication
Client side
public static partial class ServiceBusHelper
{
public static void SetServiceBusCredentials<T>(this ClientBase<T> proxy,
string secret) where T : class;
public static void SetServiceBusCredentials<T>(
this ChannelFactory<T> factory,string secret) where T : class;
...
}
MyContractClient proxy = new MyContractClient();
proxy.SetServiceBusCredentials("QV3...9M8=");
proxy.MyMethod();
proxy.Close();
Transfer Security
Securely transfer the message from client to service
What degree of client identity is in the message
Four modes for transfer security
None
Transport
Message
Mixed
public enum EndToEndSecurityMode
{
None,
Transport,
Message,
TransportWithMessageCredential //Mixed
}
Transport Security
Transfer to relay and from relay is secure
TCP uses SSL
WS uses HTTPS
Simplest and easiest to set up and use
Will never contain client's credentials
All calls are anonymous
Transport Security
Journey inside relay is insecure
Secure
Insecure
Client
Service
Transport Security
In theory relay service can
Eavesdrop on communication
Tamper with messages
In practice
Impractical given volumes of traffic
Microsoft is not the NSA
Microsoft has the highest integrity
Message Security
Transfer to relay and from relay is secure
Regardless of transport
May require setup steps
Installing service certificates in client trusted people folder
Modifying client identity address tag
Modifying client config file to list certificate
Message Security
Journey inside relay is secure
Secure
Insecure
Client
Service
Message Security
Relay service cannot
Eavesdrop on communication
Tamper with messages
In practice it is vital to assure customers of end-to-end
privacy and integrity
I recommends message security for all relayed
communication
Has additional benefits as well
Hybrid
Local security context
Message Security
Message may contain client's credentials
For service local authorization
Integration with legacy is common scenario too
Best practice is for relay service to authenticate and
authorize
Avoid burden service with unwanted traffic
No need for client credentials on service
And managing them
I recommends message security without client credentials
Anonymous towards service
When possible
Transfer Security
Streamlining host with my ServiceBusHost
public class ServiceBusHost : DiscoverableServiceHost
{
public ServiceBusHost(object singletonInstance,params Uri[] baseAddresses);
public ServiceBusHost(Type serviceType,params Uri[] baseAddresses);
public void ConfigureAnonymousMessageSecurity();
public void ConfigureAnonymousMessageSecurity(string serviceCert);
public void ConfigureAnonymousMessageSecurity(string serviceCert,
StoreLocation location,StoreName storeName);
public void ConfigureAnonymousMessageSecurity(StoreLocation location,
StoreName storeName,X509FindType findType,object findValue);
//More members
}
Transfer Security
No other setting in config or code
Requires certificate for message security
Unspecified
Reads from config file
If cert specified is empty string
Will use service namespace for certificate name
Defaults location to LocalMachine and My store
Will use RM as well
ServiceBusHost host = new ServiceBusHost(typeof(MyService));
host.ConfigureAnonymousMessageSecurity("MyServiceCert");
host.Open();
Transfer Security
Can use my declarative security
public enum ServiceSecurity
{
None,
Anonymous,
BusinessToBusiness,
Internet,
Intranet,
ServiceBus
}
[SecurityBehavior(ServiceSecurity.ServiceBus)]
class MyService : IMyContract
{...}
ServiceHost host = new ServiceHost(typeof(MyService));
host.Open();
Transfer Security
Streamline client with my ServiceBusClientBase<T>
Defaults to anonymous message security with
service namespace as cert
Can specify username creds as well
public abstract class ServiceBusClientBase<T> : ClientBase<T> where T : class
{
public ServiceBusClientBase();
public ServiceBusClientBase(string endpointName);
public ServiceBusClientBase(Binding binding,EndpointAddress remoteAddress);
public ServiceBusClientBase(string username,string password);
...
protected virtual void ConfigureForServiceBus();
protected virtual void ConfigureForServiceBus(string username,string password);
}
Transfer Security
[ServiceContract]
interface IMyContract
{
[OperationContract]
void MyMethod();
}
class MyContractClient : ServiceBusClientBase<IMyContract>,IMyContract
{
public MyContractClient()
{}
public void MyMethod()
{
Channel.MyMethod();
}
}
Resources
Programming WCF Services 3rd Edition
Juval Löwy, O'Reilly 2010
www.idesign.net
Code library
Coding standard
Sample architecture report
IDesign Method™
Architect’s Master Class
November 2011
http://www.idesign.net/idesign/download/IDesignCD.zip
More at TechEd
Discover a New WCF with Discovery
Monday 3:00 PM
The Architect
Tuesday 8:30 AM
http://northamerica.msteched.com
www.microsoft.com/teched
www.microsoft.com/learning
http://microsoft.com/technet
http://microsoft.com/msdn