General Design Guidelines
通用设计规范
1. All services must adhere to these principles:
所有的服务必须遵守这些原则:
a) Services are secure.
服务是安全的。b) Service operations leave the system in a consistent state.
服务操作保证系统在一直的状态。c) Services are thread-safe and can be accessed by concurrent clients.
服务是线程安全的并且可以被并发的客户端访问。d) Services are reliable.
服务是可靠的。e) Services are robust.
服务是健壮的。
2. Services can optionally adhere to these principles:
这些原则不是必须的。
Services are interoperable.
服务是可互操作的Services are scale-invariant.
服务是可以伸缩的Services are available.
服务是可用的
Services are responsive.
服务是可以相应的
Services are disciplined and do not block their clients for long.
服务是遵守规则的,不能长时间阻塞客户端进程。
Essentials
设计要点
Place service code in a class library,not in any hosting EXE.
服务类应该定义在类库而不是exe宿主里。2. Do not provide parameterized constructors to a service class,unless it is a singleton
that is hosted explicitly.
不要给服务类提供参数化的构造函数,除非其是singleton单例模式,并且确定宿主。
Enable reliability in the relevant bindings.
在相关的绑定里启用可靠性。4. Provide a meaningful namespace for contracts. For outward-facing services,use your
company’s URL or equivalent URN with a year and month to support versioning.
For example:
为契约定义有意义的命名空间。暴露的外部服务,使用公司的URL或URN,并附上年月日等支持版本化。
例如:
[ServiceContract(Namespace = "http://www.idesign.net/2009/06")]
interface IMyContract
{...}
For intranet services,use any meaningful unique name,such as MyApplication.
对于企业内部服务,使用唯一的有意义的名字,比如MyApplication。For example:
例如:
[ServiceContract(Namespace = "MyApplication")]
interface IMyContract
{...}
5. With intranet applications on prefer self-hosting to IIS hosting when the WAS is
unavailable.
对于企业内部应用系统,当WAS不可用的时候,推荐自托管self-hosting而不是IIS。6. Do not mix and match named bindings with default bindings. Either have all your
bindings be explicitly referenced,or use only default bindings.
不要混用指定绑定和默认绑定。要么全部明确指定绑定,要么只使用默认绑定。7. Do not mix and match named behaviors with default behaviors. Either have all your
behaviors be explicitly referenced,or use only default behaviors.
不要混用指定行为和默认行为,要么全部明确执行行为,要么使用默认行为。8. Always name all endpoints in the client config file.
在客户端的配置文件里,定义终结点的名字name.
9. Do not use SvcUtil or Visual Studio 2010 to generate a config file.
不要使用SvcUtil工具或者Visual Studio 2010去生成配置文件。10. When using a tool such as Visual Studio 2010 to generate the proxy,do clean up the
proxy.
当使用Visual Studio 2010生成客户端代理的时候,记得释放代理。11. Do not duplicate proxy code. If two or more clients use the same contract,factor the
proxy to a separate class library.
不要复制代理代码。如果两个或多个客户端使用了相同的契约,把代理分解到独立的类库里。12. Always close or dispose of the proxy.
通常要关闭或者销毁(close或dispose proxy)代理实例。(客户端代理包含网络连接等珍贵资源,继续释放)13. When using discovery,prefer dynamic addresses.
当使用服务发现机制的时候,推荐动态地址。(动态定位服务地址是WCF服务发现的优势)14. When using discovery,do support the Metadata exchange endpoint over TCP.
当使用服务发现机制的时候,记得暴露支持TCP元数据交换的终结点。(这里指的是Ad-Hoc模式,适用于企业局域网,提高数据交换速度)15. When using discovery,avoid cardinality of “some”.
当使用服务发现机制的时候,避免使用不确定的基数(WCF4.0里,查找终结点的个数,这里明确数目,FindCriteria.MaxResults = 1)
Service Contracts
服务契约
Always apply the ServiceContract attribute on an interface,not a class:
把ServiceContract属性标记到契约接口上,而不是服务类上
//Avoid:避免
[ServiceContract]
class MyService
{
[OperationContract]
public void MyMethod()
{...}
}
//Correct:正确
[ServiceContract]
interface IMyContract
{
[OperationContract]
void MyMethod();
}
class MyService : IMyContract
{
public void MyMethod()
{...}
}
Prefix the service contract name with an I:
服务契约名称以I开头
[ServiceContract]
interface IMyContract
{...}
3. Avoid property-like operations:
避免定义与属性类似的操作
//Avoid:
[ServiceContract]
interface IMyContract
{
[OperationContract]
string GetName();
[OperationContract]
void SetName(string name);
}
4. Avoid contracts with one member.
避免契约里只包含一个成员
5. Strive to have three to five members per service contract.
每个契约里尽量保证3-5个成员
6. Do not have more than 20 members per service contract. Twelve is probably the
practical limit.
每个服务契约里成员不要超过20个。12个也许久应该就是极限
Data Contracts
数据契约
1. Avoid inferred data contracts (POCO). Always be explicit and apply the
DataContract attribute.
避免使用推测性的数据契约。明确使用DataContract属性定义数据契约。Use the DataMember attribute only on properties or read-only public members.
只在属性或者只读的成员上使用DataMember属性Avoid explicit XML serialization on your own types.
自己的类型上明确使用XML序列化标记Avoid message contracts.
避免使用消息契约5. When using the Order property,assign the same value to all members coming from
the same level in the class hierarchy.
当使用Order属性的时候,对于类层次相同的所有成员赋相同的值6. Support IExtensibleDataObject on your data contracts. Use explicit interface
implementation.
数据契约支持IExtensibleDataObject。使用明确地实现接口。7. Avoid setting IgnoreExtensionDataObject to true in the
ServiceBehavior and CallbackBehavior attributes. Keep the default of
false.
避免在ServiceBehavior和CallbackBehavior属性里把IgnoreExtensionDataObject设置为true。保持默认的false8. Do not mark delegates and events as data members.
不要使用委托和事件作为数据成员
9. Do not pass .NET-specific types,such as Type,as operation parameters.
不要传递.NET-specific类型,比如Type,作为操作参数。10. Do not accept or return ADO.NET DataSets and DataTables (or their type-safe
subclasses) from operations. Return a neutral representation such as an array.
不要接受或者返回ADO.NET DataSets和DataTables (或它们的类型安全的子类)。返回一个中立的数据形式,比如数组。11. Suppress the generation of a generic type parameter hash code and provide a legible
type name instead.
不要产生泛型类型参数的哈希值,使用一个易懂的类型名称作为替代。
Instance Management
实例管理1. Prefer the per-call instance mode when scalability is a concern.
当考虑到可伸缩性的时候,使用Per_Call模式,单调模式。2. If setting SessionMode.NotAllowed on the contract,always configure the service instancing mode as InstanceContextMode.PerCall 如果在契约上设置了SessionMode.NotAllowed,通常会把服务实例模式设置为InstanceContextMode.PerCall3. Do not mix sessionful contracts and sessionless contracts in the same service.
不要在一个服务里把会话契约和非会话契约混用。4. Avoid a singleton unless you have a natural singleton.
避免使用单例模式,除非理所当然地应该使用单例模式。5. Use ordered delivery with a sessionful service.
尽量在会话服务里使用顺序传递。6. Avoid instance deactivation with a sessionful service.
避免在会话服务里停止服务实例7. Avoid demarcating operations.
避免分布操作(比如有先后顺序的操作。)8. With durable services,always designate a completing operation.
在持久化服务里,始终指定一个完成操作。
支持可信赖会话的绑定包括WSHttpBinding,WSDualHttpBinding,WSFederationBinding以及NetTcpBinding和NetNamedPipesBinding
Operations and Calls
操作与调用1. Do not treat one-way calls as asynchronous calls.
不要把单向调用作为异步调用2. Do not treat one-way calls as concurrent calls.
不要把单向调用作为并发调用3. Expect exceptions from a one-way operation.
单向操作也应该返回异常4. Enable reliability even on one-way calls. Use of ordered delivery is optional for one way calls.
即使当单向调用的时候,也要启用可靠性。单向调用不必使用有序传递。5. Avoid one-way operations on a sessionful service. If used,make it the terminating operation:
避免在会话服务里使用单向调用。如果用到,作为结束操作。
[ServiceContract(SessionMode = SessionMode.required)]
interface IMyContract
{
[OperationContract]
void MyMethod1();
[OperationContract(IsOneWay = true,IsInitiating = false,IsTerminating =true)]
void MyMethod2();
}
6. Name the callback contract on the service side after the service contract name,suffixed by Callback:
回调操作最好使用服务契约的名字加后缀Callback
interface IMyContractCallback
{...}
[ServiceContract(CallbackContract = typeof(IMyContractCallback))]
interface IMyContract
{...}
7. Strive to mark callback operations as one-way.
回调操作标记会单向操作8. Use callback contracts for callbacks only.
只在回调的时候使用回调契约。9. Avoid mixing regular callbacks and events on the same callback contract.
避免在回调契约上混用常规回调和事件10. Event operations should be well designed:
事件操作应该设计如下:a) Avoid return type, void
避免返回类型b) No out-parameters
没有out参数c) Marked as one-way operations
标记为单向操作11. Avoid using raw callback contracts for event management,and prefer using the publish-subscribe framework.
避免在事件管理中使用原始回调契约,推荐使用发布-订阅框架12. Always provide explicit methods for callback setup and teardown:
为回调提供清晰的安装(setup)和拆卸 ( teardown)方法
[ServiceContract(CallbackContract = typeof(IMyContractCallback))]
interface IMyContract
{
[OperationContract]
void DoSomething();
[OperationContract]
void Connect();
[OperationContract]
void Disconnect();
}
interface IMyContractCallback
{...}
13. Use the type-safe DuplexClientBase<T,C> instead of
DuplexClientBase<T> 使用类型安全的DuplexClientBase<T,C>代替DuplexClientBase<T>14. Use the type-safe DuplexChannelFactory<T,"serif"; color: #000081; font-size: 10pt; mso-font-kerning: 0pt;" lang="EN-US">instead of
DuplexChannelFactory<T> 使用类型安全的DuplexChannelFactory<T,C>代替DuplexChannelFactory<T>15. When debugging or in intranet deployment of callbacks over the WSDualHttpBindingCallbackBaseAddressBehavior attribute with CallbackPort set to 0 当调试或在企业局域网部署环境里使用WSDualHttpBinding时,使用CallbackBaseAddressBehavior ,并把 CallbackPort设置0:
[CallbackBaseAddressBehavior(CallbackPort = 0)]
class MyClient : IMyContractCallback
{...}
Faults
错误1. Never use a proxy instance after an exception,even if you catch that exception.
不要异常以后使用代理实例,尽管你捕获了异常。2. Avoid fault contracts and allow WCF to mask the error.
避免错误契约,让WCF来包装错误3. Do not reuse the callback channel after an exception even if you catch that exception,as the channel may be faulted.
不要在异常后还使用回调通道,尽管你捕获了异常,因为通道可能出于错误状态。4. Use the FaultContract attribute with exception classes,as opposed to mere serializable types:
在异常类上使用FaultContract属性,而不是可序列化类型上:
//Avoid:避免
[OperationContract]
[FaultContract(typeof(double))]
double Divide(double number1,double number2);
//Correct:正确
[OperationContract]
[FaultContract(typeof(DivideByZeroException))]
double Divide(double number1,double number2);
5. Avoid lengthy processing such as logging in IErrorHandler.ProvideFault() 避免冗长的处理,比如登入IErrorHandler.ProvideFault()6. With both service classes and callback classes,set IncludeExceptionDetailInFaults in debug sessions,either in the config file or programmatically:
对于服务类和回调类,在调试时,设置IncludeExceptionDetailInFaults为true,配置文件或者编程都可以:
public class DebugHelper
{
public const bool IncludeExceptionDetailInFaults =
#if DEBUG
true;
#else
false;
#endif
}
[ServiceBehavior(IncludeExceptionDetailInFaults =
DebugHelper.IncludeExceptionDetailInFaults)]
class MyService : IMyContract
{...}
7. In release builds,do not return unknown exceptions as faults except in diagnostic scenarios.
在发布构建版本里,不要返回不可知的异常做为错误,除非是在调试场景里。8. Consider using the ErrorHandlerBehavior attribute on the service,both for promoting exceptions to fault contracts and for automatic error logging:
当提升异常为错误契约,以及自动错误日志时,都可以考虑在服务上使用ErrorHandlerBehavior属性:
[ErrorHandlerBehavior]
class MyService : IMyContract
{...}
9. Consider using the CallbackErrorHandlerBehaviorAttribute on the callback client,both for promoting exceptions to fault contracts and for automatic
error logging:
当提升异常为错误契约,以及自动错误日志时,考虑在回调客户端上使用CallbackErrorHandlerBehaviorAttribute:
[CallbackErrorHandlerBehavior(typeof(MyClient))]
class MyClient : IMyContractCallback
{
public void OnCallabck()
{...}
}
Transactions
事务1. Never manage transactions directly.
不要直接管理事务2. Apply the TransactionFlow attribute on the contract,not the service class.
在契约而不是服务类上标注TransactionFlow属性,3. Do not perform transactional work in the service constructor.
不要在服务的构造函数里执行事务操作4. Using this book’s terminology,configure services for either Client or Client/Service transactions. Avoid None or Service transactions.
使用本书中的术语,为客户端或客户端/服务端事务模式配置服务。避免使用None或服务事务模式。5. Using this book’s terminology,configure callbacks for either Service or Service/Callback transactions. Avoid None or Callback transactions.
使用本书中的术语,为服务或服务/回调事务模式配置回调。避免使用None或回调事务模式。6. When using the Client/Service or Service/Callback mode,constrain the binding to flow transactions using the BindingRequirement 当使用客户端/服务或服务/回调模式,通过BindingRequirement属性约束绑定传播事务7. On the client,always catch all exceptions thrown by a service configured for None or Service transactions.
在客户端,始终捕获None或服务事务里抛出的所有异常。8. Enable reliability and ordered delivery even when using transactions.
即使使用事务的时候,也要启用可靠性和顺序传递9. In a service operation,never catch an exception and manually abort the transaction:
在服务操作里,不要捕获异常并终止事务
//Avoid:避免
[OperationBehavior(TransactionScoperequired = true)]
public void MyMethod()
{
try
{
...
}
catch
{
Transaction.Current.Rollback();
}
}
10. If you catch an exception in a transactional operation,always rethrow it or another exception.
如果你在一个事务性操作里捕获了异常,始终直接重新抛出这个异常或者抛出另外一个异常11. Keep transactions short.
保持事务简洁12. Always use the default isolation level of IsolationLevel.Serializable 使用IsolationLevel.Serializable默认的事物隔离级别13. Do not call one-way operations from within a transaction.
不要在事务内部调用一个单向操作14. Do not call nontransactional services from within a transaction.
不要在一个事务内部调用一个非事务服务15. Do not access nontransactional resources (such as the filesystem) from within a transaction.
不要在一个事务内访问非事务性资源(比如文件系统)16. With a sessionful service,avoid equating the session boundary with the transaction boundary by relying on auto-complete on session close.
对于会话服务,避免因为会话关闭时的auto-complete就把会话边界和事务边界等价。17. Strive to use the TransactionalBehavior attribute to manage transactions on sessionful services:
尽量使用TransactionalBehavior属性去管理会话服务上的事务
[Serializable]
[TransactionalBehavior]
class MyService : IMyContract
{
public void MyMethod()
{...}
}
18. When using a sessionful or transactional singleton,use volatile resource managers to manage state and avoid explicitly state-aware programming or relying on WCF’s
instance deactivation on completion.
当使用会话或事务性的单例服务时,使用易失资源管理器去管理状态,并且避免显示地使用状态编程或者在完整时依赖WCF实例钝化机制,19. With transactional durable services,always propagate the transaction to the store by setting SaveStateInOperationTransaction to true.
在持久性事务服务里,始终通过设置SaveStateInOperationTransaction 为true来把事务和传播到存储系统中。
Concurrency Management
并发管理1. Always provide thread-safe access to:
对以下资源始终提供线程安全的访问a) Service in-memory state with sessionful or singleton services
会话或者单例服务在内存中的状态b) Client in-memory state during callbacks
回调期间客户端在内存中的状态c) Shared resources
共享资源d) Static variables
静态变量2. Prefer ConcurrencyMode.Single (the default). It enables transactional access and provides thread safety without any effort.
默认情况推荐使用ConcurrencyMode.Single模式。它会启用事务性访问并提供线程安全,而不会带来任何开销。3. Keep operations on single-mode sessionful and singleton services short in order to avoid blocking other clients for long.
当操作在是单个会话模式或者单例模式时,请保证操作简短,以长时间免阻塞客户端。4. When using ConcurrencyMode.Multiple 当使用ConcurrencyMode.Multiple时,你必须启用事务autocompletion自动提交机制。5. Consider using ConcurrencyMode.Multiple on per-call services to allow concurrent calls.
在单调服务上使用ConcurrencyMode.Multiple属性,允许并发调用,6. Transactional singleton service with ConcurrencyMode.Multiple must have ReleaseServiceInstanceOnTransactionComplete set to false 使用ConcurrencyMode.Multiple的事务性单例服务必须把ReleaseServiceInstanceOnTransactionComplete 设置为 false
[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single,
ConcurrencyMode = ConcurrencyMode.Multiple,
ReleaseServiceInstanceOnTransactionComplete = false)]
class MySingleton : IMyContract
{...}
7. Never self-host on a UI thread,and have the UI application call the service.
不要在UI线程上托管服务,让UI程序只调用服务。8. Never allow callbacks to the UI application that called the service unless the callback posts the call using SynchronizationContext.Post() 从不允许服务回调UI程序,除非回调使用了SynchronizationContext.Post()9. When supplying the proxy with both synchronous and asynchronous methods,apply the FaultContract attribute only to synchronous methods.
当代理提供了异步和同步方法的时候,在同步方法上使用FaultContract10. Keep asynchronous operations short. Do not equate asynchronous calls with lengthy operations.
保持异步调用操作简短。不要把异步调用和冗长的操作混淆。11. Do not mix transactions with asynchronous calls.
不要把事务和异步调用混用
Queued Services
队列服务1. On the client,always verify that the queue (and a dead-letter queue,when applicable) is available before calling the queued service. Use QueuedServiceHelper.VerifyQueues() for this purpose.
在客户端,在调用队列服务以前,始终检查队列是否可用(如果可以的话,也包括确认死信队列)。使用QueuedServiceHelper.VerifyQueues()方法检查。2. Always verify that the queue is available when hosting a queued service (this is done automatically by ServiceHost<T>).
当托管队列服务的时候始终检查队列是否可用(ServiceHost<T>会自动检测)3. Except in isolated scenarios,avoid designing the same service to work both queued and non-queued.
除了某些单独的场景,避免避免在同一个服务里同时使用队列和非队列服务4. The service should participate in the playback transaction.
服务应该参与到回放事务中5. When participating in the playback transaction,avoid lengthy processing in the queued service.
当参与到回放事务里,避免队列服务里出现冗长的处理工作6. Avoid sessionful queued services.
避免使用绘画性队列服务7. When using a singleton queued service,use a volatile resource manager to manage the singleton state.
当使用单例队列服务时,使用易失资源管理器去管理单例状态8. When using a per-call queued service,explicitly configure the contract and the service to be per-call and sessionless:
当使用单调队列服务时,明确设置服务和契约的单调和非回话属性
[ServiceContract(SessionMode = SessionMode.NotAllowed)]
interface IMyContract
{...}
[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall)]
class MyService : IMyContract
{...}
9. Always explicitly set contracts on a queued singleton to disallow sessions:
始终禁止在单例队列服务模式下使用会话
[ServiceContract(SessionMode = SessionMode.NotAllowed)]
interface IMyContract
{...}
[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single)]
class MyService : IMyContract
{...}
10. The client should call a queued service inside a transaction.
客户端应该在一个事务内部调用队列服务11. On the client side,do not store a queued service proxy in a member variable.
在客户端,不要在成员变量里存储队列服务的代理12. Avoid relatively short values of TimeToLive 避免使用相对短的TimeToLive值,因为这会干扰队列服务的决策13. Avoid nontransactional queues.
避免非事务性队列14. When using a response queue,have the service participate in the playback transaction and queue the response in that transaction.
当使用一个应答队列时,让服务参与到一个回放事务中,并且在事务里,把应答消息装入队列。15. Have the response service participate in the response playback transaction.
让应答服务参与到应答回放事务里16. Avoid lengthy processing in a queued response operation.
避免在应答操作里进行冗长的处理工作17. With MSMQ 3.0,prefer a response service to a poison queue service dealing with failures of the service itself.
对于MSMQ3.0,推荐使用应答服务来处理服务自身失败,而不是毒信队列18. With MSMQ 4.0,use ReceiveErrorHandling.Reject for poison messages unless you have advanced processing with ReceiveErrorHandling.MoveAvoid ReceiveErrorHandling.Fault and ReceiveErrorHandling.DropMSMQ4.0,除非对ReceiveErrorHandling.Move有高级处理,否则为毒信队列使用ReceiveErrorHandling.Reject,避免使用ReceiveErrorHandling.Fault 和 ReceiveErrorHandling.Drop19. With MSMQ 4.0,consider the use of a response service to handle service playback failures.
考虑使用应答服务去处理服务回放错误20. Unless dealing with a sessionful contract and service,never assume the order of queued calls.
除非处理会话契约和服务,否则从不假定队列调用是有序的21. Avoid multiple service endpoints sharing a queue.
避免多个服务终结点共享一个队列22. Avoid receive context.
避免使用接收上下文环境
Security
安全1. Always protect the message and provide for message confidentiality and integrity.
始终保护消息,并为消息提供安全性和完整性2. In an intranet,you can use Transport security as long as the protection level is set to EncryptAndSign 在企业网内,只要你把保护级别设置为EncryptAndSign你可以使用传输安全,3. In an intranet,avoid impersonation. Set the impersonation level to TokenImpersonationLevel.Identification 在企业网内,避免使用impersonation,把impersonation 级别设置为TokenImpersonationLevel.Identification4. When using impersonation,have the client use TokenImpersonationLevel.Impersonation 当使用impersonation时,让客户端使用TokenImpersonationLevel.Impersonation5. Use the declarative security framework and avoid manual configuration.
使用声明式安全框架,并避免手动配置6. Never apply the PrincipalPermission attribute directly on the service class:
从不在服务上直接设置PrincipalPermission属性
//Will always fail:
[PrincipalPermission(SecurityAction.Demand,Role = "...")]
public class MyService : IMyContract
{...}
7. Avoid sensitive work that requires authorization at the service constructor.
避免在服务构造函数上完成需要授权的工作8. Avoid demanding a particular user,with or without demanding a role:
避免要求一个特定的用户,不管是否要求的角色
//Avoid:
[PrincipalPermission(SecurityAction.Demand,Name = "John")]
public void MyMethod()
{...}
9. Do not rely on role-based security in the client’s callback operations.
不要在客户端回调操作里依赖基于角色的安全10. With Internet clients,always use Message security.
Internet客户端,始终使用消息安全11. Allow clients to negotiate the service certificate (the default).
运行客户端与服务端进行证书协商(默认)12. Use the ASP.NET providers for custom credentials.
为自定义客户端凭据使用ASP.NET providers
13. When developing a custom credentials store,develop it as a custom ASP.NET provider.
当开发自定义客户端凭据存储的时候,使用自定义ASP.NET provider.
14. Validate certificates using peer trust.
使用对等信任验证证书
The Service Bus
服务总线1. Prefer the TCP relay binding.
推荐使用TCP Relay绑定2. Make your services be discoverable.
让你的服务是可以被发现3. Do use discrete events.
使用分离事件4. Do not treat buffers as queues.
不要把缓存当做队列5. With buffers,avoid raw WCF messages and use the strongly typed,structured calls technique of BufferedServiceBusHost<T> and BufferedServiceBusClient<T> 对于缓存,避免原始的WCF消息以及使用强类型、结构化的BufferedServiceBusHost<T> 和 BufferedServiceBusClient<T>调用方法6. Use message security.
使用消息安全7. Do not use service bus authentication for user authentication.
不要是有服务总线验证去做用户验证的工作8. Strive for anonymous calls and let the service bus authenticate the calling application.
Resources
资源
1 Programming WCF Services 3rd Edition
By Juval Lowy,O'Reilly 2010
2 The WCF Master Class
The world’s best,most intense WCF training starts by explaining the motivation for
service-orientation and then continues to discuss in depth how to develop serviceoriented
applications using WCF. You will see how to take advantage of built-in features
such as service hosting,instance management,asynchronous calls,synchronization,
reliability,transaction management,disconnected queued calls and security. While the
class shows how to use these features,it sets the focus on the ‘why’ and the rationale
behind particular design decisions,often shedding light on poorly-documented and
understood aspects. You will learn not only WCF programming but also relevant design
guidelines,best practices,and pitfalls. The material presented includes IDesign's original
techniques and utilities and goes well beyond anything you can find in conventional
sources. Don’t miss out on this unique opportunity to learn WCF from the IDesign
architects who have been part of the strategic design effort for WCF from the beginning,"serif"; color: black; font-size: 10pt; mso-font-kerning: 0pt;" lang="EN-US">and who offer a profound insight on the technology and its applications. Any .NET
developer or architect would benefit greatly from the class.
More at www.idesign.net
3 The Architect’s Master Class
The Architect’s Master Class is a 5 days training,and is the ultimate resource for the
professional architect. The class has three parts,on process,technology & SOA,and the
IDesign method for analysis and design. The class shows the architect how to take an
active leadership role on all three aspects,as a continuum,since when executing a design,"serif"; color: black; font-size: 10pt; mso-font-kerning: 0pt;" lang="EN-US">one cannot separate process from design from technology – all three have to work in
concert. You will see relevant design guidelines,and pitfalls,"serif"; color: black; font-size: 10pt; mso-font-kerning: 0pt;" lang="EN-US">crucial process required of today’s modern architects. Don’t miss on this unique
opportunity to learn and improve your architecture skills with IDesign,and share their
passion for architecture and software engineering.
4 The IDesign Serviceware Downloads
The IDesign serviceware downloads are a set of original techniques,tools,utilities and
even breakthroughs developed by the IDesign architects. The utilities are largely
productivity-enhancing tools,or they compensate for some oversight in the design of
.NET or WCF. The demos are also used during our Master Classes to demystify technical
points,as lab exercises or to answer questions. The classes' attendees find the demos
useful not only in class but after it. The demos serve as a starting point for new projects
and as a rich reference and samples source.
www.idesign.net