WCF 简单架构(一) 契约和客户端

来源:互联网 发布:数据挖掘 教学大纲 编辑:程序博客网 时间:2024/06/06 05:52


先画个图 。

其中:

 1)  WcfRequest,WcfResponse,IWcfService 组成契约的基本

 2)  WcfServiceBase为实现契约部分也就是 wcf服务

 3) WcfClient为契约的使用方,也就是wcf客户端




WCF 通用契约定义用于所有交互的调用的基接口。

其中WcfRequest和WcfResponse 作为输入输出参数的封装

    [ServiceContract]    public interface IWcfService     {        [OperationContract]        WcfResponse Request(WcfRequest req);    }


为了通用其中返回参数和输入参数多用object, 后面具体的实现时使用WCF特性用于限定范围

如: 需要具体类型的定义时可使用 ServiceKnownTypeAttribute 来进行定义 


   [ServiceContract]    [ServiceKnownType("GetKnownTypes", typeof(UserEntity))]    public interface IWcfHello : IWcfService    {    }

但这样用起来不是太方便,可参考MSDN 官网的例子 , 用一个外部类进行类型集合的整理

业务契约定义

[ServiceContract]   [ServiceKnownType("GetKnownTypes", typeof(Helper))]    public interface IWcfService    {    }

Helper类定义 及方法GetKnownTypes

  static class Helper    {        public static IEnumerable<Type> GetKnownTypes(ICustomAttributeProvider provider)        {            System.Collections.Generic.List<System.Type> knownTypes =                new System.Collections.Generic.List<System.Type>();            knownTypes.Add(typeof(UserEntity));            //knownTypes.Add(...);            return knownTypes;        }    }


wcf 客户端有多种使用方法,其中.net使用,微软提供了类ClientBase, 只要实现此类就能方便使用 , 在这里加上自定义的泛型约束,可限制此类的使用范围

加入 两个方法, 分别于用调用有返回和没有返回的方法。

/// <summary>    /// wcf客户端基类    /// </summary>    /// <typeparam name="TChannel">基于IWcfService的类型</typeparam>    public abstract class WcfClient<TChannel> : ClientBase<TChannel>, IDisposable        where TChannel : class, IWcfService    {        /// <summary>        /// 默认的wcf绑定参数        /// </summary>        protected static NetTcpBinding wcfBinding;        static WcfClient()        {            wcfBinding = new NetTcpBinding();            wcfBinding.Security.Mode = SecurityMode.None;        }        /// <summary>        /// 用户指定的wcf绑定配置        /// </summary>        protected Binding binding;        /// <summary>        /// wcf连接地址        /// </summary>        protected EndpointAddress remoteAddress;        /// <summary>        /// 构造函数        /// </summary>        /// <param name="edpAddr">连接地址</param>        protected WcfClient(EndpointAddress edpAddr)            : base(wcfBinding, edpAddr) { this.binding = wcfBinding; this.remoteAddress = edpAddr; }        /// <summary>        /// 构造函数        /// </summary>        /// <param name="binding">wcf绑定配置</param>        /// <param name="edpAddr">连接地址</param>        protected WcfClient(Binding binding, EndpointAddress edpAddr)            : base(binding, edpAddr) { this.binding = wcfBinding; this.remoteAddress = edpAddr; }        private WcfResponse Request(string methodName, params object[] parameters)        {            WcfRequest req = new WcfRequest();            req.Head.RequestMethodName = methodName;            req.Head.ClassName = this.GetType().Name;            if (parameters != null)                req.Body.Parameters = parameters;            return base.Channel.Request(req);        }        /// <summary>        /// 执行wcf方法并返回数据        /// </summary>        /// <typeparam name="Return">返回类型</typeparam>        /// <param name="methodName">方法名</param>        /// <param name="parameters">参数</param>        /// <returns>返回结果</returns>        protected virtual Return RequestFunc<Return>(string methodName, params object[] parameters)        {            var res =  Request( methodName, parameters);            if (res.Head.IsSuccess)                return (Return)res.Body.Data;            // 返回不是真 抛出异常            throw new MyException(res.Head.Message);        }         /// <summary>        /// 执行wcf方法没有返回数据        /// </summary>        /// <param name="methodName">方法名</param>        /// <param name="parameters">参数</param>        protected virtual void RequestAction(string methodName, params object[] parameters)        {            var res = Request(methodName, parameters);            if (res.Head.IsSuccess)                return;            // 返回不是真 抛出异常            throw new MyException(res.Head.Message);        }    }


在使用时可直接继承此类,加入需要使用的业务接口。

业务接口:

    public interface IHello     {        string CallHello(UserEntity user);        int Times();        void Reset();    }

客户端调用类

 public class WcfClientHello : WcfClient<IWcfHello>, IHello    {        public WcfClientHello(EndpointAddress addr)            : base(addr)        {        }                 public string CallHello(UserEntity user)        {            return base.RequestFunc<string>("CallHello", new object[] { user });         }        public int Times()        {            return base.RequestFunc<int>("Times");        }        public void Reset()        {            base.RequestAction("Reset");        }    }


这样外部直接就能这样使用了

 var client = new WcfClientHello(addr);                 var str = client.CallHello(new UserEntity { Name = "mmx", Age = 132 });

完整的测试代码 点击打开链接


0 0
原创粉丝点击