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


先画个图 。

其中:

 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 });

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


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值