WinForm企业应用框架设计——笔记

来源:互联网 发布:数据加密标准 编辑:程序博客网 时间:2024/06/05 19:47

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

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

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

WinForm企业应用框架设计【四】动态创建业务窗体

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

拜读之后,觉得还是写写笔记记得牢一些,如下:

界限划分与动态创建WCF服务(no svc!no serviceActivations!

一:界限划分

如图所示,几个程序集的含义如下:

XL.Client【客户端程序】

XL.DataAccess 【数据库访问层】

XL.Models 【实体层】

XL.Service【WCF服务层】

XL.ServiceAPI 【服务接口】(全部是接口)

XL.Setup【安装包】

这就是一个典型的CS程序的程序集列表

客户端中:

XL.Client将引用 XL.Models和XL.ServiceAPI

服务端 中:

XL.Service将引用 XL.Models和XL.ServiceAPI和XL.DataAccess

二:动态创建WCF服务

创建wcf服务通过工厂类实现,遍历程序集后,找到以service结束的类,放入RouteTable中。

原则:约定由于配置的原则!

 

团队内部的约定和客户端按约定识别WCF服务

1:关于职责问题

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

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

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

2关于容错的问题

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

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

3 安全性问题

a使用数字证书

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

c用加密狗启动客户端

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

4框架复用的问题

我脚的一个框架  并不是给成百上千个项目用,很多时候只是给一两个、两三个项目用

5团队内部的约定

约定一:

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

约定二:

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

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

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

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

约定三:

实体类名必须以Model结尾

窗体类名必须以Form结尾

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

6按约定动态发现WCF服务(客户端)

 

 

框架窗体设计+动态创建菜单

1框架窗体

框架窗体分管布局的只有四个Panel;

上、下、左、右。(搞过EXTJS的人比较喜欢说成东、南、西、北)-_-!

最上面的Panel是存放顶级菜单用的 (top menu)

最下面的panel是存放状态信息和系统版本用的

左边的Panel又分为两个panel

2动态创建顶部菜单

先看CreateTopMenu

/// <summary>

/// 创建顶部菜单

/// </summary>

private void CreateTopMenu()

{

    var tmms = (from v in Menus where v.ParentId == Guid.Empty orderby v.OrderNum select v).ToList();

    for (var i = 0; i < tmms.Count; i++)

    {

        var ctl = CreateOneTopMenu(tmms[i], i);

        TopMenuP.Controls.Add(ctl);

    }

}

Createonetopmenu(m,i)函数会自动在pannel中创建控件,并绑定一些常用事件。注意这些事件是这些控件公用的事件,比如鼠标放上去,颜色变色等。

3动态创建子菜单

private void CreateSubMenu(MenuModeltm)

{

    SubHeaderLB.Text =tm.MenuName;

    SubMenuP.Controls.Clear();

    var smms = (from v in Menus where v.ParentId == tm.Idorderby v.OrderNum select v).ToList();

    for (var i = 0; i <smms.Count; i++)

    {

        var ctl = CreateOneSubMenu(smms[i], i);

        SubMenuP.Controls.Add(ctl);

    }

}

 

 

动态创建业务窗体

1自定义Tab按钮

我们的tab按钮左部是文字;右部是关闭按钮;并定义了鼠标划入状态,选中状态等。

然后再根据鼠标的位置以不同的颜色绘制控件,此部分涉及到gdi+的内容。

2业务窗体的基类

即点击菜单兰后,如何弹出对应窗体呢?我们把每个窗体放在菜单栏按钮的tag中,点击时先判断tag中保存了什么menumodel,再根据CreateOneForm(menumodel)创建对应的窗体。

private BaseForm CreateOneForm(MenuModel m)

       {

           var ass = this.GetType().Assembly;

           var url = string.Format("XL.Client.Forms.{0}", m.Url);

           BaseForm f = null;

           try

           {

                f = ass.CreateInstance(url) asBaseForm;

           }

           catch

           {

                Utils.Alert("没有与此菜单相关的业务窗体");

                return null;

           }

           f.Dock = DockStyle.Fill;

           f.FormMenu = m;

           var tabBtn = new TabBTN();

           tabBtn.OnClose += new EventHandler(f.tbn_OnClose);

           tabBtn.OnSelect += new EventHandler(f.tbn_OnSelect);

           tabBtn.Caption = m.MenuName;

           int left = 6;

           var tabCount = TabContainerP.Controls.Count;

           if (tabCount > 0)

            {

                var lastTab =TabContainerP.Controls[tabCount - 1];

                left += (lastTab.Left +lastTab.Width);

           }

           tabBtn.Left = left;

           TabContainerP.Controls.Add(tabBtn);

           f.FormTabBTN = tabBtn;

           return f;

       }

 

系统登录以及身份验证+源码

1登录的画面与客户端逻辑

当点击登录之后,

会把用户输入的用户名和密码传迪到服务端,并得到当前用户实体

CacheStrategy.CurUser= CurUser;

2每次与WCF交互都传递标识信息

登录之后的每次服务端交互,服务端都要确认当前的客户端的正确性。为了做到这一点,我们就要在每次与WCF交互的时候,把客户端的身份传递给服务器端,并在服务端缓存起来。

3服务端的验证

为了对客户端的操作进行身份验证,我们设计了一个所有服务类的基类

[AspNetCompatibilityRequirements(RequirementsMode =AspNetCompatibilityRequirementsMode.Required)]
[ServiceBehavior(IncludeExceptionDetailInFaults = true)]

此两个类属性放在服务基类里,服务子类就不用再写这两个属性了

4客户端对验证消息的处理

在服务端基类里我们对验证不通过的客户抛出了一个异常

如果异常,服务端“特意”返回的

我们就让客户端重新登录

 

结语,读完之后感觉对wcf这块还是要加强学习,不太懂~~再研究下源码!


0 0