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

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

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

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

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

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

先来张图片!我们这个系列就是要做一个这样的框架! 

 

我曾写过几个“系列”的东西,如 PL/SQL学习笔记 ;T-SQL学习笔记(这是CSDN的精华帖); jquery框架分析

jquery框架分析写了一篇就被我送进了“净身房”成了“太监”

 园子里也有很多朋友写“系列文章”,写着写着就太监了;

我对此深表理解!尤其是做项目的人~身不由己啊!

顺便问一下haibindev 您的《c# 实现p2p文件分享与传输系统》 完结了吗?我还等着看呢~

好了言归正传

我承诺这个系列将包含以下这些内容

1.一个简单的面向服务编程的框架的搭建

2.动态创建WCF(no svc!no serviceActivations!)

3.客户端根据约定自动识别WCF服务

4.客户端框架窗体(如上图所示)

5.动态菜单与动态业务窗体

如果反响不错~我将加入如下内容

6.组织架构和人事管理

7.角色权限控制

8.自定义打包工具

 

好吧~真正的言归正传

一:界限划分

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

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

 

实体层中各个实体的实例携带着数据,像JJ一样不停的穿梭于客户端和服务端之间-_-!

【上句话在2011-12-2修改】

 

XL.Service中针对每个业务都将有一个WCF服务与之对应,

每个服务类型都实现了XL.ServiceAPI中的一个接口

XL.Client中通过XL.ServiceAPI中的这些接口调用服务

 

XL.DataAccess 负责持久化数据和从数据库中取数

二:动态创建WCF服务

 在Application_Start中加入如下代码

        protected void Application_Start(object sender, EventArgs e)
        {
            ServiceRegister.RegisterAllService();
        }

ServiceRegister的代码如下:

    /// <summary>
    /// 为了进一步拓展,才定义了自己的ServiceHostFactory
    /// </summary>
    public class MyServiceHostFactory : ServiceHostFactory
    {
        protected override ServiceHost CreateServiceHost(Type serviceType, Uri[] baseAddresses)
        {
            var result = base.CreateServiceHost(serviceType, baseAddresses);
            return result;
        }
    }
    public static class ServiceRegister
    {
        private static ServiceHostFactory wshf;
        /// <summary>
        /// 静态构造函数只执行一次
        /// </summary>
        static ServiceRegister()
        {
            wshf = new MyServiceHostFactory();
        }
        /// <summary>
        /// 通过反射注册服务
        /// </summary>
        public static void RegisterAllService()
        {

            var ass = (typeof(ServiceRegister)).Assembly;
            var ts = ass.GetTypes();
            foreach (var t in ts)
            {
                //约定:类型名以Service结尾的为WCF服务类型
                if (t.Name.EndsWith("Service"))
                {
                    var serviceName = t.FullName.Substring("XL.Service.".Length);
                    serviceName = serviceName.Replace(".", "-");
                    var sr = new ServiceRoute(serviceName, wshf, t);
                    RouteTable.Routes.Add(sr);
                }
            }
        }
    }

【上面的代码2011-11-30 23.00.00修改】

【上面的代码2011-12-03 23.34.00修改】

好吧,我承认这是动态注册WCF服务的核心代码

想动态创建WCF服务ServiceHostFactory是必不可少的~

(服务的工厂嘛~看名字就知道啦~)

其次我们循环创建了ServiceRoute的实例

ServiceRoute是“允许创建支持 REST 方案的 HTTP 服务路由”

(我们动态创建的服务路由只支持HTTP的绑定,也是这里造成的)

然后把这些服务路由都存到RouteTable中,放到RouteTable中只是注册了服务路由,并没有启动服务

但当客户端试图绑定这个服务的时候,服务会自行启动!it's amazing!

在这个代码中,我们约定以Service结尾的类型就是WCF服务类型

亲~这是约定优于配置的原则哦~

当然我们应该为特例留下生存空间,我这里没有做,亲,你自己实现吧

这虽然是核心代码,但没有配置文件也是不行的

  <system.web>
    <compilation debug="true" targetFramework="4.0"/>
  </system.web>
  <system.serviceModel>
    <serviceHostingEnvironment aspNetCompatibilityEnabled="true" />
  </system.serviceModel>

接着在看看WCF服务的代码

    [AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
    [ServiceBehavior(IncludeExceptionDetailInFaults = true)]
    public class MenuService:IMenu
    {
        MenuDA da = new MenuDA();
        public List<MenuModel> GetAllMenu()
        {
            var result = da.GetAllModels();
            return result;
        }
        public bool EditMenu(MenuModel target)
        {
            var result = da.Update(target);
            return result;
        }
    }

AspNetCompatibilityRequirements的属性是指这个服务应在asp.net兼容模式下运行

基于IIS的WCF有两种模式,一种是ASP.NET并行,一种是ASP.NET兼容;

这些内容超出了咱们这篇文章的范畴了~就不多说了

ServiceBehavior的属性要求把错误发送给客户端,也可以在这里定义其他的服务端行为

类里面的MenuDA就是数据库访问层的代码了~我就不贴出来了

 

好下面看看这个服务的接口IMenu

    [ServiceContract]
    public interface IMenu
    {
        [OperationContract]
        List<MenuModel> GetAllMenu();
        [OperationContract]
        bool EditMenu(MenuModel target);
    }

服务契约和操作契约的属性标记一如往常,就不多说了

 

这些工作做完之后;发布到IIS下;

http://localhost/XL.Service/[YourType]Service

这就是一个服务;

如果XL.Service程序集下有多个服务类型的话,将产生出多个服务。

好吧~到此为止

------

下一节我们就说怎么动态识别这些服务~

另外有个朋友让我帮着做一个打包工具

这个工具能够自动识别客户端有没有.net环境,如果没有,将先安装.net framework,再安装他的程序,我也打算写出来后放到博客上

相对于下一节的内容来说~

您更希望我先写哪个内容呢??

期待朋友们的回复!

-----

另外

在很早之前与ArtechFrank Xu Lei交流过NO SVC的技术细节~

在此表示感谢!两位都是WCF领域的大牛

时间: 2024-09-20 00:04:18

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

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

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

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

本系列第一篇发出来之后,与钧梓昊逑讨论了一些问题,现整理出来 (钧梓昊逑是我的入门老师~非常牛的技术天才~现在开始涉足西洋乐器领域~希望他能早日超过贝多芬~为山寨党众同仁争光~) 一:关于职责问题 客户端的主要职责负责呈现,不宜有过多的业务逻辑 与业务相关的代码和访问数据库相关的代码放在服务器端 与呈现相关的代码放在客户端  至于哪些代码是与业务相关的,哪些代码是与呈现相关的 呈现的代码是不是包含了业务,业务的代码是不是牵涉到呈现 这属于边界划分的问题,仁者见仁~智者见智~也要根据项目具体问题具

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