WinForm企业应用框架设计【二】团队内部的约定和客户端按约定识别WCF服务

本系列第一篇发出来之后,与钧梓昊逑讨论了一些问题,现整理出来

(钧梓昊逑是我的入门老师~非常牛的技术天才~现在开始涉足西洋乐器领域~希望他能早日超过贝多芬~为山寨党众同仁争光~)

一:关于职责问题

客户端的主要职责负责呈现,不宜有过多的业务逻辑

与业务相关的代码和访问数据库相关的代码放在服务器端

与呈现相关的代码放在客户端 

至于哪些代码是与业务相关的,哪些代码是与呈现相关的

呈现的代码是不是包含了业务,业务的代码是不是牵涉到呈现

这属于边界划分的问题,仁者见仁~智者见智~也要根据项目具体问题具体分析

 

二:关于容错的问题

容错代码服务端和客户端都有

业务上的容错放在服务端,交互上的容错放在客户端

(如果客户端不是自己做的,那么服务端的容错就要全部包含,这不是咱们讨论的范畴)

交互上的容错和业务上的容错是不一样的

服务端认为接收到的数据在格式上都是正确的,但在业务上不一定正确。

 

三:安全性问题

如果是安全性要求相对较高的领域,比如金融领域

就要仔细考虑到客户端验证的问题 ,

1使用数字证书

2在SOAP消息头里加入一串DES密文

3用加密狗启动客户端

4通过硬件串号来识别客户端

各有利弊~自己权衡~不深入讨论

 

四:框架复用的问题

我脚的一个框架  并不是给成百上千个项目用,

很多时候只是给一两个、两三个项目用

所以不要把过多精力花在兼容不同的业务问题上

或许有人会说这么做是为了最大限度的复用这个框架,

这也要看各自把握的程度了~仁者见仁~智者见智~

只给一个项目用的框架~也挺好~

能把很多业务上的东西抽象到框架中,减少编码人员的工作量,框架也不显着复杂难用!

----------------

五:关于ORM

本系列中没用用到ORM~下一个系列中会用到~这不是承诺

好吧~言归正传

一:团队内部的约定

我们根据主菜单把系统的业务划分成12块

(当然会根据业务的增加而增加新的模块,不会影响既有框架)

下面看一下程序集的目录结构

当我们的框架设计完成之后

要求编码人员按照约定好的目录结构完成  相应的业务代码

编码人员几乎不用关心任何与自己业务无关的内容。

约定一:

每个模块的代码放到相应的文件夹下去

约定二:

WCF服务接口类名必须以I开头;

WCF服务类名必须以Service结尾;

接口类名去掉I字母  ==  服务类名去掉Service结尾

亲~要不然客户端会找不到服务哦

约定三:

实体类名必须以Model结尾

窗体类名必须以Form结尾

数据库访问类名必须以DA结尾

----

如果你觉得这些约定实在过于繁琐~

好吧~随便你~

二:按约定动态发现WCF服务

有了上面的约定,想要动态发现WCF服务,就简单了

看代码

    public class ClientFactory<TClient> : IDisposable
    {
        static EndpointAddress serviceAddress;
        static BasicHttpBinding binding;
        ChannelFactory<TClient> factory;
        public TClient CreateClient()
        {
            factory = new ChannelFactory<TClient>(binding, serviceAddress);
            TClient result = factory.CreateChannel();
            return result;
        }
        static ClientFactory()
        {
            var surl = ConfigurationManager.AppSettings["ServiceURL"];
            var iname = typeof(TClient).FullName.Substring("XL.ServiceAPI.".Length);
            iname = iname.Replace(".I", "-");
            var sname = string.Format("{0}Service", iname);
            var url = Path.Combine(surl, sname);
            serviceAddress = new EndpointAddress(url);

            binding = new BasicHttpBinding();
            binding.CloseTimeout = new TimeSpan(10, 10, 10);
            binding.OpenTimeout = new TimeSpan(10, 10, 10);
            binding.SendTimeout = new TimeSpan(10, 10, 10);
            binding.ReceiveTimeout = new TimeSpan(10, 10, 10);
        }
        public void Dispose()
        {
            factory.Close();
        }
    }

这个类需要一个“类型形参”,这个类型形参就是我们的服务接口类型

静态的构造函数只会执行一次

appconfig文件中放着WCF服务的基础地址

<configuration>
  <appSettings>
    <add key="ServiceURL" value="http://localhost/XL.Service" />
  </appSettings>
</configuration>

接下来就是按照游戏规则构造出了一个WCF Service的地址

形如:http://localhost/XL.Service/Sys-MenuService  

(亲~我修改了上一篇中创建服务的内容~)

静态的构造函数做的主要还是准备工作,CreateClient方法才是真正的创建了服务通道

 它反馈的是一个TClient的实例。

也就是一个实现了WCF服务接口的实例,我们可以使用这个实例来调用WCF服务

下面我们看看如何调用WCF

            var factory = new Common.ClientFactory<IMenu>();
            try
            {
                var Menus = factory.CreateClient().GetAllMenu();
            }
            catch (Exception ex)
            {
                Utils.Alert(ex.Message);
            }
            factory.Dispose();

如你所见,我们使用了什么接口类型作为类型形参

CreateClient就会反馈给我们什么类型的信道实例

我们就可以用这个信道实例,完成WCF接口描述的各种行为了

 

下一节咱们就说客户端框架窗体和动态菜单了~~

 

另:

xuefly读了很多书~学习能力非常强~

但同时他也是强烈的种族主义者~中国版的希特勒~(用希特勒形容他,他肯定以为我在侮辱他)

好吧~学飞~你再不给我点推荐我就真不跟你玩了~

---

同时~读到这篇文章的朋友们~你如果觉得还有点意思~就点一下推荐吧~~~

 

时间: 2024-11-27 12:29:14

WinForm企业应用框架设计【二】团队内部的约定和客户端按约定识别WCF服务的相关文章

WinForm企业应用框架设计【一】界限划分与动态创建WCF服务(no svc!no serviceActivations!)

WinForm企业应用框架设计[一]界限划分与动态创建WCF服务(no svc!no serviceActivations!) WinForm企业应用框架设计[二]团队内部的约定和客户端按约定识别WCF服务 WinForm企业应用框架设计[三]框架窗体设计:动态创建菜单: WinForm企业应用框架设计[四]动态创建业务窗体 WinForm企业应用框架设计[五]系统登录以及身份验证+源码 先来张图片!我们这个系列就是要做一个这样的框架!    我曾写过几个"系列"的东西,如 PL/SQ

WinForm企业应用框架设计【五】系统登录以及身份验证+源码

索引 WinForm企业应用框架设计[一]界限划分与动态创建WCF服务(no svc!no serviceActivations!) WinForm企业应用框架设计[二]团队内部的约定和客户端按约定识别WCF服务 WinForm企业应用框架设计[三]框架窗体设计:动态创建菜单: WinForm企业应用框架设计[四]动态创建业务窗体 WinForm企业应用框架设计[五]系统登录以及身份验证+源码 闲话休提~ 一:登录的画面与客户端逻辑 为了在打开程序的时候先弹出登录窗体 我们修改了主窗体的构造函数

WinForm企业应用框架设计【三】框架窗体设计;动态创建菜单;

要不是我的朋友乔乔==乔不死跟我聊到领域驱动设计~ 我也不会发现第一篇中关于"充血实体"的错误说法(至少~我写文章的时候~内心的想法是错的~) 我个人不是很喜欢领域驱动设计~感觉这种思路(我们暂且叫它思路~虽然它有一些既有的原则和模式) 重点要求架构师深入到业务领域中去~ 但是在国内往往很难真正的与领域专家做深入交流~ 架构师划分的领域模型和聚合往往与真实的情况差别较大~ 即使划分的较好~新的业务和变化的业务也另设计师非常头疼~ 另外 设计师很难将庞大复杂的业务抽象成领域模型 往往需要

SilverLight企业应用框架设计【一】整体说明

Silverlight企业应用框架设计[六]自定义系统菜单(使用自己的DataForm) SilverLight企业应用框架设计[五]客户端调用服务端(使用JSON传递数据,自己实现RESTful Web服务) SilverLight企业应用框架设计[四]实体层设计+为客户端动态生成服务代理(自己实现RiaService) SilverLight企业应用框架设计[三]服务端设计 SilverLight企业应用框架设计[二]框架画面 SilverLight企业应用框架设计[一]整体说明 闲言碎语~

SilverLight企业应用框架设计【五】客户端调用服务端(使用JSON传递数据,自己实现RESTful Web服务)

来个索引 SilverLight企业应用框架设计[四]实体层设计+为客户端动态生成服务代理(自己实现RiaService) SilverLight企业应用框架设计[三]服务端设计 SilverLight企业应用框架设计[二]框架画面 SilverLight企业应用框架设计[一]整体说明   在上一节中讲到的自动生成的服务代理类核心代码,如下 public event ServiceEventHandler Completed; public void GetAllMenu() { var si

Silverlight企业应用框架设计【六】自定义系统菜单(使用自己的DataForm)

索引 SilverLight企业应用框架设计[五]客户端调用服务端(使用JSON传递数据,自己实现RESTful Web服务) SilverLight企业应用框架设计[四]实体层设计+为客户端动态生成服务代理(自己实现RiaService) SilverLight企业应用框架设计[三]服务端设计 SilverLight企业应用框架设计[二]框架画面 SilverLight企业应用框架设计[一]整体说明   首先我们设计的窗体如下 xaml代码如下: <location:BasePage x:Cl

SilverLight企业应用框架设计【二】框架画面

框架画面分为上中下三层 由下面一个Grid控件完成布局 <Grid x:Name="LayoutRoot"> <Grid.RowDefinitions> <RowDefinition Height="60"></RowDefinition> <RowDefinition Height="*"></RowDefinition> <RowDefinition Height=

SilverLight企业应用框架设计【四】实体层设计+为客户端动态生成服务代理(自己实现RiaService)

题外话: 对不住各位,本打算年前把这个系列写完,结果由于杂务缠身一直推到年后 我特别痛恨我自己!我觉得不但对不起各位!也对不起自己. 最近烦躁不安,不能专心向学.也不知道如何是好. -- 好吧,言归正传 说个前提条件: 此项目虽然使用了silverlight 4.0 但是服务端只能在dotNet3.5下运行 这也是我们为什么自己实现riaService的原因 实体层设计 由于有这个限制条件,我们设计的实体层也有所区别 如下图为实体层的程序集(只有MenuM实体类,其他实体类未加入.) 下面来看一

SilverLight企业应用框架设计【三】服务端设计

一:缓存服务类型与方法 客户端请求的时候 为了方便的知道请求的类型与类型所包含的方法 我们把服务类型和方法缓存到静态字典中了 代码如下 public class WCFRouteTable { static Dictionary<string, Type> routeService; static Dictionary<string, MethodInfo> routeMethods; static WCFRouteTable() { routeService = new Dict