一、摘要
场景:
最近公司的项目中用到了WCF 就想着分析OEA里的WCF设计,吸取一下高手的经验 。
类图:
今天在这里主要是分析OEA里的WCF设计(也叫分布式业务对象数据门户)。先看一下OEA类库
二、本文大纲
a、摘要 。
b、本文大纲 。
c、WCF接口设计。
d、WCF 交互设计 。
e、数据门户设计 。
f、业务对象知识补充 。
三、WCF接口设计
关于WCF接口的相关知识可以看以前写WCF 开发日志 -- WCF契约设计
消息契约(MessageContract) 在 WCF 开发日志 -- WCF契约设计 有提到一点,在网上和MSDN上有更详细的说明了,这里就不详细描述了。
WcfResponse , FetchRequest , UpdateRequest上面类图对应有三个文件,其实这三个文件的内容都差不多,只是职责不同。
四、WCF 交互设计
服务端实现:
红色部分就是WCF适配到数据门户来进行与数据库交互否实现业务逻辑。1: /// <summary>2: /// 使1用?WCF实现的统一的数据门户3: ///4: /// 标记了ConcurrencyMode.Multiple 来表示多线程进行5: /// </summary>6: [ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall, ConcurrencyMode = ConcurrencyMode.Multiple, UseSynchronizationContext = false)]7: [AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]8: public class WcfPortal : IWcfPortal9: {10: /// <summary>11: /// Get an existing business object.12: /// </summary>13: /// <param name="request">The request parameter object.</param>14: public WcfResponse Fetch(FetchRequest request)15: {
16: OEA.Server.DataPortalFacade portal = new OEA.Server.DataPortalFacade();17: object result;18: try19: {20: result = portal.Fetch(request.ObjectType, request.Criteria, request.Context);
21: }
22: catch (Exception ex)23: {
24: result = ex;
25: }
26: return new WcfResponse(result);27: }
28:
29: /// <summary>30: /// Update a business object.31: /// </summary>32: /// <param name="request">The request parameter object.</param>33: public WcfResponse Update(UpdateRequest request)34: {
35: OEA.Server.DataPortalFacade portal = new OEA.Server.DataPortalFacade();36: object result;37: try38: {39: result = portal.Update(request.Object, request.Context);
40: }
41: catch (Exception ex)42: {
43: result = ex;
44: }
45: return new WcfResponse(result);46: }
47: }
48:
客服端直接使用WCF的代理类ChannelFactory实现1: /// <summary>2: /// Implements a data portal proxy to relay data portal3: /// calls to a remote application server by using WCF.4: /// </summary>5: public class WcfProxy : OEA.DataPortalClient.IDataPortalProxy,IDataPortalServer6: {7: #region IDataPortalProxy Members8:
9: /// <summary>10: /// Gets a value indicating whether the data portal11: /// is hosted on a remote server.12: /// </summary>13: public bool IsServerRemote14: {
15: get { return true; }16: }
17:
18: #endregion19:
20: #region IDataPortalServer Members21:
22: private string _endPoint = "WcfDataPortal";23:
24: /// <summary>25: /// Gets or sets the WCF endpoint used26: /// to contact the server.27: /// </summary>28: /// <remarks>29: /// The default value is WcfDataPortal.30: /// </remarks>31: protected string EndPoint32: {
33: get34: {35: return _endPoint;36: }
37: set38: {39: _endPoint = value;40: }
41: }
42:
43: /// <summary>44: /// Returns an instance of the channel factory45: /// used by GetProxy() to create the WCF proxy46: /// object.47: /// </summary>48: protected virtual ChannelFactory<IWcfPortal> GetChannelFactory()49: {
50: return new ChannelFactory<IWcfPortal>(_endPoint);51: }
52:
53: /// <summary>54: /// Returns the WCF proxy object used for55: /// communication with the data portal56: /// server.57: /// </summary>58: /// <param name="cf">59: /// The ChannelFactory created by GetChannelFactory().60: /// </param>61: protected virtual IWcfPortal GetProxy(ChannelFactory<IWcfPortal> cf)62: {
63: return cf.CreateChannel();64: }
65:
66: /// <summary>67: /// Called by <see cref="DataPortal" /> to load an68: /// existing business object.69: /// </summary>70: /// <param name="objectType">Type of business object to create.</param>71: /// <param name="criteria">Criteria object describing business object.</param>72: /// <param name="context">73: /// <see cref="Server.DataPortalContext" /> object passed to the server.74: /// </param>75: public DataPortalResult Fetch(Type objectType, object criteria, DataPortalContext context)76: {
77: ChannelFactory<IWcfPortal> cf = GetChannelFactory();78: IWcfPortal svr = GetProxy(cf);79: WcfResponse response = null;80: try81: {82: response =
83: svr.Fetch(new FetchRequest(objectType, criteria, context));84: if (cf != null)85: cf.Close();
86: }
87: catch88: {89: cf.Abort();
90: throw;91: }
92:
93: object result = response.Result;94: if (result is Exception)95: throw (Exception)result;96: return (DataPortalResult)result;97: }
98:
99: /// <summary>100: /// Called by <see cref="DataPortal" /> to update a101: /// business object.