View
223
Download
1
Category
Tags:
Preview:
Citation preview
Design Patterns, Practices, and Techniques with the Azure AppFabric Service Bus
Juval LowyIDesignwww.idesign.net
©2011 IDesign Inc. All rights reserved
About Juval Löwy
Software architectConsults and trains on .NET architecture and technology
Microsoft's Regional Director for the Silicon ValleyRecent book
Programming WCF Services 3rd Edition (2010 O’Reilly)Participates in the .NET/WCF design reviewsPublishes at MSDN and other magazinesRecognized Software Legend by Microsoft Contact at www.idesign.net
Agenda
What is the service busBrief
TechniquesPublishing to registryDiscrete eventsDiscoveryExplorerStructured buffersResponse service
Bonus MaterialTime permitting
Azure AppFabric Service Bus
While designed to address connectivity issues also providesScalabilityAvailabilitySecurity Lower technology entrance barrier by making advanced scenario main-stream and mundane
Internet connectivity is hardFirewalls Load balancers Sessions NAT
Why Service Bus
Service
H/W Firewall
Router
LB
NAT
S/W Firewall
Client
Private IPsDiscovery and registryVirtualizationProxy servers
SecurityIT in general…
Why Service Bus
Scalability throughput and availability challenges Opening your Intranet
Requires DMZClients credentials management
Commonplace solutionsCumbersomeNot real-timePotentially insecure
Why Service Bus
SolutionDo not connect clients to services directly
At least not initially
Use a relay service
Relay service in the cloud Neutral territoryOnly requires outbound calls to establish connection
Allowed in most environments
Will relay client calls to serviceAdditional benefits of scalability, security, administration
Service Bus Relay
RelayService
Client Service
12
4
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 service4. Relay forwards message to service
3
Azure AppFabric Service Bus
Ready-made service bus relay serviceDMZ in the skyOnly allows authenticated authorized callsRepels 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 httpsBinding 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 ExplorerCan administer buffers as well
Service Bus Bindings
The three main bindings NetTcpRelayBindingNetOnewayRelayBindingNetEventRelayBinding
TCP Relay Binding
Binding of choice in most casesBest 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 sessionClients gets the same instance
Not interoperableUses 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-wayMessage goes into a buffer
Messages limited to 64 KBUsed sb for scheme
<endpoint address = "sb://MyNamespace.servicebus.windows.net/..." binding = "netOnewayrelayBinding" contract = "..."/>
Event Relay Binding
Specialization of one-way relay
Allows any number of services to monitor bufferN:M communication
Can safely listen concurrently on nested URIsFor whatever reason
Clients may still call over NetOnewayRelayBindingServices must use NetEventRelayBinding
public class NetEventRelayBinding : NetOnewayRelayBinding{...}
Service Bus as Events Hub
EventsHub
Publisher
Publisher
Subscriber SubscriberSubscriber
Service Bus as Events Hub
Light weight pub/sub systemNo administrative supportNo 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
<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"/>
To manage events at the operation level need to map URIs to operations not endpoints
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 codeExpensive
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 hostRequires base address(es)
Appends contract name to each base address
Can accept binding to useDefaults for secure binding
No need for config fileCan 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();
host.Close();
Service Bus as Events Hub
Subscriptions stored in dictionary Maps subscribed operations per contractCan add admin supportUse a tool to manage subscriptions outside scope of host/serviceManage 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 handlingpublic 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 proxyCareful to match expected endpoints layout
Automate proxy with my ServiceBusEventsClientBaseAppends contract name and operation to base addressNo need for config file
Only needs base address
Always uses one way relay bindingUsed 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 IntranetDiscovery is useful
Loosely-coupled clients and servicesDynamic addressesEasy 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 busCan substitute events binding for UDP
Discovery requests Announcements
Mimic WCF discovery behavior
Solution Architecture
Streamline with my helpersIServiceBusDiscovery for discovery requests
Events relay binding Supported by discoverable servicesProvides 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);}
DiscoveryRequests
Client
Service
RelayServiceRelay
ServiceRelay
Service
1
2
3
IServiceBusDiscovery
IServiceBusDiscoveryCallback
Operation
Event
Discoverable Host
My DiscoverableServiceHostUsed like regular hostTo 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 requestsAddress defaults to URI "DiscoveryRequests"
Configurable via DiscoveryAddress property
Uses plain events binding to receive requests Configurable via DiscoveryRequestBinding property
Calls back client using IServiceBusDiscoveryCallbackUses plain one way binding
Configurable via DiscoveryResponseBinding property
Discoverable Host
Uri baseAddress = new Uri("sb://...");
ServiceHost host = new DiscoverableServiceHost(typeof(MyService,baseAddress);
//Address is dynamichost.AddServiceEndpoint(typeof(IMyContract),new NetTcpRelayBinding(), Guid.NewGuid().ToString());
host.Open();
Discovery Client
For client use my ServiceBusDiscoveryClientModeled 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();
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 Helper
Helper class
Service Bus Discovery 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;}
Helper factory
Announcements
Can use events binding to support announcementsMy 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);}
Announcements
Client
Service
RelayService
1
2
IServiceBusAnnouncements
Operation
Event
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 behaviorDefaults to announcing on "AvailabilityAnnouncements" URI under service namespace
Configurable via AnnouncementsAddress property
Calls client using plain one way bindingConfigurable 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;}}
Supports IServiceBusAnnouncementsHosted as singleton published to registrySubscribes to events
Defaults to "AvailabilityAnnouncements" URI Configurable via AnnouncementsAddress property
Uses plain events bindingConfigurable via AnnouncementsBinding property
Client can subscribe to events or access addresses container
Announcements
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 InternetAlmost
Every junction in the service bus can host a buffer
Sender
Reader
Service Bus Buffers
Buffer does not equate queueNot durable
Data loss with catastrophic crash of service busNot transactional
Not long lasting messagesMax is 10 minutes
Buffers are limited Up to 50 messages
In between queued calls and fire-and-forget calls
Service Bus Buffers
Aimed atAsync callsChunky callsMostly connected applications on somewhat shaky connections One-way callsElastic Internet wire
Service Bus Buffers
All messages are one-wayNo 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 messagesRaw 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 getResults Errors
Client can provide dedicated response buffer for service Should pass response address and method ID in headers
Automate with my framework
Response Service
ClientService
Service Buffer
ResponseService
Response Buffer
Bonus Material
Service Bus Security
Security Aspects
Service bus authentication Message transfer security
Service Bus Authentication
Service must authenticate to connect to service busClient 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 messagesReading messages Manage service namespace
Service and client may not use the same token
Service Bus Authentication
Can streamline with my extension methodDefaults 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();
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();
Service Bus Authentication
Client side
Transfer Security
Securely transfer the message from client to serviceWhat degree of client identity is in the messageFour modes for transfer security
NoneTransportMessage Mixed
public enum EndToEndSecurityMode{ None, Transport, Message, TransportWithMessageCredential //Mixed}
Transport Security
Transfer to relay and from relay is secureTCP uses SSLWS uses HTTPS
Simplest and easiest to set up and useWill never contain client's credentials
All calls are anonymous
Transport Security
Journey inside relay is insecure
Client Service
Secure Insecure
Transport Security
In theory relay service can Eavesdrop on communicationTamper 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 secureRegardless of transport
May require setup stepsInstalling service certificates in client trusted people folderModifying client identity address tagModifying client config file to list certificate
Message Security
Journey inside relay is secure
Client Service
Secure Insecure
Message Security
Relay service cannot Eavesdrop on communicationTamper with messages
In practice it is vital to assure customers of end-to-end privacy and integrityI recommends message security for all relayed communication
Has additional benefits as wellHybrid Local security context
Message Security
Message may contain client's credentialsFor service local authorizationIntegration 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 credentialsAnonymous towards serviceWhen 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 codeRequires certificate for message securityUnspecified
Reads from config file
If cert specified is empty string Will use service namespace for certificate name
Defaults location to LocalMachine and My storeWill 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 certCan 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 EditionJuval Löwy, O'Reilly 2010
www.idesign.netCode libraryCoding standardSample architecture reportIDesign Method™
Architect’s Master ClassNovember 2011
http://www.idesign.net/idesign/download/IDesignCD.zip
More at TechEd
Discover a New WCF with DiscoveryMonday 3:00 PM
The ArchitectTuesday 8:30 AM
Resources
www.microsoft.com/teched
Sessions On-Demand & Community Microsoft Certification & Training Resources
Resources for IT Professionals Resources for Developers
www.microsoft.com/learning
http://microsoft.com/technet http://microsoft.com/msdn
http://northamerica.msteched.com
Connect. Share. Discuss.
Recommended