业务类接口在TCP,HTTP,BLL模式下的实例 设计模式混搭 附源码一份

WinForm酒店管理软件--框架这篇随笔可以说是我写的最被大家争议的随笔,一度是支持和反对是一样的多。大家对我做的这个行业的前景有很大的建议啊。虽然市场有困难,但好技术架构肯定是前提。事实也是,当你还是一个孩子准备和一群成年人竞争时,你可以被人轻易的暴力推到,可以被人家多年的经验轻松完虐,别人也会说“大人说话小孩子一边玩去”。这些都是过程,作为一位有准备的小孩会有心理准备的,今天准备把之前的架构中的使用策略实现业务类接口在TCP,HTTP,BLL模式下的实例大家一起交流下。这样说大家可能比较模糊,

我提几个问题。

  1、之前有人问我IBLL是干什么的?    

  例如:

   [ServiceContract]
public interface IRadioListBLL
{
[OperationContract(IsOneWay = false)]
List<RD_RADIO_LIST> Query();
}
 RD_RADIO_LIST

using System;
using Yike.Model.DataBase;
using System.Runtime.Serialization;

namespace Yike.Model.Radio
{
/// <summary>
/// 无线电清单
/// </summary>
[DataContract]
public class RD_RADIO_LIST
{
/// <summary>
///
/// </summary>
[DataMember]
[FieldProperty(PRIMARY_KEY = 1, COLUMN_TYPE = "NUMBER", COLUMN_LENGTH = 22)]
public long REDIO_UKID
{
get;
set;
}
/// <summary>
///
/// </summary>
[DataMember]
[FieldProperty(PRIMARY_KEY = 0, COLUMN_TYPE = "VARCHAR2", COLUMN_LENGTH = 20)]
public string REDIO_NAME
{
get;
set;
}
/// <summary>
///
/// </summary>
[DataMember]
[FieldProperty(PRIMARY_KEY = 0, COLUMN_TYPE = "VARCHAR2", COLUMN_LENGTH = 100)]
public string URL
{
get;
set;
}
/// <summary>
///
/// </summary>
[DataMember]
[FieldProperty(PRIMARY_KEY = 0, COLUMN_TYPE = "VARCHAR2", COLUMN_LENGTH = 100)]
public string DESCRIPTION
{
get;
set;
}
/// <summary>
///
/// </summary>
[DataMember]
[FieldProperty(PRIMARY_KEY = 0, COLUMN_TYPE = "NUMBER", COLUMN_LENGTH = 22)]
public long PRIORITY
{
get;
set;
}
}
}

RD_RADIO_LIST

  首先如@心态要好说的IBLL是业务逻辑层接口,而且还实现wcf的服务契约描述。当然了这个接口和实体是使用Easycord生成的。

  2、上篇中wcf在架构中起的什么作用?

    我们的UI层可能是window、wince。开发语言可能是c#也可能是java。这样我们业务层实现多套肯定不是最好的。很多人在UI层一个操作时会进行数据校验,我通常喜欢将这些校验放在业务层进行。这样我通过wcf提供标准的服务、大家都可以来直接调用不用担心调用前辈的服务自己有什么验证忘记判断,使用wcf客户端不用直接连接数据库,这样安全性、部署的难度都可以有很大改善。

  通过上面的解说,大家应该知道,访问wcf可以用性能比较好的TCP协议,也可以使用可以不用担心防火墙等的Http协议,当然有的时候我们确实需要直接连接数据库。这就是我想说的根据IBLL实现TCP,HTTP,BLL模式访问业务层。

  不啰嗦啦,直接上图:

  

  设计模式的思想可以肯定的说每个程序员都在用,而且肯定不止一种。只不过有的人是通过gof的相关书籍,有的人是通过同事的经验传授...。总结为每一个设计模式方便大家交流和学习。很多设计模式的名字都忘记了,最近又温故了下gof设计模式,有兴趣的小伙伴们可以来161153385设计模式群一起交流。

  在上图中可以看出来至少使用了工厂模式、策略模式、还有模版模式。

    工厂模式:InterfaceHelper的Factory方法是你给我一个接口我给你实例,不管你怎么实现。

    策略模式:这么说就是见招拆招。你要什么我给你什么模式下的实例。      

           switch (_InstanceSource)
{
case "BLL": iGetInstance = new BLLGetInstance(); break;
case "WsHttp": iGetInstance = new WSHttpGetInstance(); break;
case "WsTcp": iGetInstance = new WSTcpGetInstance(); break;
}

    模版模式:InterfaceHelper在Init中需要初始化加载类和服务和接口。在家每个业务层的时候基本都是一样的,需要加载BLL,IBLL,服务的文件,循环类,保存在字典中。

LoadType(string bllFile, string iBllFile, string serverFile)中就是一个模版。

Init()会通过这个模版初始化字典表中。

     private static void Init()
{
string docPath = path + "\\Assembly.xml";
if (File.Exists(docPath))
{
XDocument xdoc = XDocument.Load(docPath);
foreach (XElement element in xdoc.Element("AssemblyInfos").Elements())
{
LoadType(element.Attribute("BLLFileName").Value, element.Attribute("IBLLFileName").Value, element.Attribute("ServeFileName").Value);
}
}
}
 附源码一份

using System;
using System.Collections.Generic;
using System.Configuration;
using System.IO;
using System.Reflection;
using System.ServiceModel;
using System.Xml.Linq;

namespace Yike.Tool.Instance
{
public class InterfaceHelper
{
private static string _InstanceSource = string.Empty;
private static List<BllTypeRelation> dict = new List<BllTypeRelation>();

private static string path
{
get
{
return Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
}
}

public static T Factory<T>()
{
if (string.IsNullOrEmpty(_InstanceSource))
_InstanceSource = GetInstanceSource();
if (dict == null || dict.Count == 0)
Init();
IGetInstance iGetInstance = null;
switch (_InstanceSource)
{
case "BLL": iGetInstance = new BLLGetInstance(); break;
case "WsHttp": iGetInstance = new WSHttpGetInstance(); break;
case "WsTcp": iGetInstance = new WSTcpGetInstance(); break;
}
if (iGetInstance == null)
return default(T);
BllTypeRelation t = dict.Find(d => d.IBll == typeof(T));
if (t != null)
return iGetInstance.GetInstance<T>(t);
else
throw new Exception(path + "不存在");
}

private static string GetInstanceSource()
{
string InstanceSource = string.Empty;
if (ConfigurationManager.AppSettings["InstanceSource"] == null)
InstanceSource = "BLL";
else
InstanceSource = ConfigurationManager.AppSettings["InstanceSource"];
return InstanceSource;
}

private static void Init()
{
string docPath = path + "\\Assembly.xml";
if (File.Exists(docPath))
{
XDocument xdoc = XDocument.Load(docPath);
foreach (XElement element in xdoc.Element("AssemblyInfos").Elements())
{
LoadType(element.Attribute("BLLFileName").Value, element.Attribute("IBLLFileName").Value, element.Attribute("ServeFileName").Value);
}
}
}

private static void LoadType(string bllFile, string iBllFile, string serverFile)
{
if (!File.Exists(path + "\\" + bllFile + ".dll") || !File.Exists(path + "\\" + iBllFile + ".dll"))
return;

Assembly bllAssembly = Assembly.LoadFile(path + "\\" + bllFile + ".dll");
Assembly iBllAssembly = Assembly.LoadFile(path + "\\" + iBllFile + ".dll");
Assembly serverAssembly = null;
if (File.Exists(path + "\\" + serverFile + ".dll"))
serverAssembly = Assembly.LoadFile(path + "\\" + serverFile + ".dll");

Type[] types = bllAssembly.GetTypes();

foreach (Type type in types)
{
string name = type.Name.Replace("BLL", "");
Type t1 = iBllAssembly.GetType(iBllFile + ".I" + type.Name);
Type t2 = null;
if (serverAssembly != null)
t2 = serverAssembly.GetType(serverFile + "." + name + "Server");
if (t1 == null)
continue;
dict.Add(new BllTypeRelation(type, t1, t2));
}

}
}

public class BllTypeRelation
{
public BllTypeRelation(Type bll, Type ibll, Type server)
{
this.Bll = bll;
this.IBll = ibll;
this.Server = server;
}

public Type Bll
{
get;
set;
}

public Type IBll
{
get;
set;
}

public Type Server
{
get;
set;
}
}

public interface IGetInstance
{
T GetInstance<T>(BllTypeRelation t);
}

public class BLLGetInstance : IGetInstance
{
public T GetInstance<T>(BllTypeRelation t)
{
return (T)Activator.CreateInstance(t.Bll);
}
}

public class WSHttpGetInstance : IGetInstance
{
public T GetInstance<T>(BllTypeRelation t)
{
string url = "http://" + ConfigurationManager.AppSettings["ServerIp"] + ":" + ConfigurationManager.AppSettings["ServerPort"] + "/" + t.Server.Name + ".svc";
EndpointAddress ea = new EndpointAddress(url);
return ChannelFactory<T>.CreateChannel(new WSHttpBinding(SecurityMode.None), ea);
}
}

public class WSTcpGetInstance : IGetInstance
{
public T GetInstance<T>(BllTypeRelation t)
{
string url = "net.tcp://" + ConfigurationManager.AppSettings["ServerIp"] + ":" + ConfigurationManager.AppSettings["ServerPort"] + "/" + t.Server.Name + ".svc";

EndpointAddress ea = new EndpointAddress(url);

return ChannelFactory<T>.CreateChannel(new NetTcpBinding(SecurityMode.None), ea);
}
}
}

附源码一份

 
 

业务类接口在TCP,HTTP,BLL模式下的实例 设计模式混搭 附源码一份的更多相关文章

  1. 利用Java针对MySql封装的jdbc框架类 JdbcUtils 完整实现(包含增删改查、JavaBean反射原理,附源码)

    最近看老罗的视频,跟着完成了利用Java操作MySql数据库的一个框架类JdbcUtils.java,完成对数据库的增删改查.其中查询这块,包括普通的查询和利用反射完成的查询,主要包括以下几个函数接口 ...

  2. 基于Python接口自动化测试框架+数据与代码分离(进阶篇)附源码

    引言 在上一篇<基于Python接口自动化测试框架(初级篇)附源码>讲过了接口自动化测试框架的搭建,最核心的模块功能就是测试数据库初始化,再来看看之前的框架结构: 可以看出testcase ...

  3. C#/ASP.NET MVC微信公众号接口开发之从零开发(四) 微信自定义菜单(附源码)

    C#/ASP.NET MVC微信接口开发文章目录: 1.C#/ASP.NET MVC微信公众号接口开发之从零开发(一) 接入微信公众平台 2.C#/ASP.NET MVC微信公众号接口开发之从零开发( ...

  4. C#/ASP.NET MVC微信公众号接口开发之从零开发(三)回复消息 (附源码)

    C#/ASP.NET MVC微信接口开发文章目录: 1.C#/ASP.NET MVC微信公众号接口开发之从零开发(一) 接入微信公众平台 2.C#/ASP.NET MVC微信公众号接口开发之从零开发( ...

  5. Asp.net MVC - 使用PRG模式(附源码)

    阅读目录: 一. 传统的Asp.net页面问题 二.Asp.net MVC中也存在同样的问题 三.使用PRG模式 四.PRG模式在MVC上的实现 一. 传统的Asp.net页面问题 一个传统的Asp. ...

  6. Eclipse开发环境debug模式调试断点从jar跳到源码

    Eclipse开发环境debug模式调试断点从jar跳到源码 说明:本案例使用jsch-0.1.54.jar和源码做test,项目分成两个,一个是jsch的源码,另一个是测试案例 一.下载JSch.的 ...

  7. 3.NetDh框架之缓存操作类和二次开发模式简单设计(附源码和示例代码)

    前言 NetDh框架适用于C/S.B/S的服务端框架,可用于项目开发和学习.目前包含以下四个模块 1.数据库操作层封装Dapper,支持多种数据库类型.多库实例,简单强大: 此部分具体说明可参考博客: ...

  8. 使用工厂方法模式实现多数据库WinForm手机号码查询器(附源码)

    先讲一下简单工厂模式.工厂方法模式.抽象工厂模式的东西: 简单工厂模式(Simple Factory Pattern):工厂类中包含了必要的逻辑判断,根据客户端的选择条件动态实例化相关类,也就是说产品 ...

  9. 2.NetDh框架之简单高效的日志操作类(附源码和示例代码)

    前言 NetDh框架适用于C/S.B/S的服务端框架,可用于项目开发和学习.目前包含以下四个模块 1.数据库操作层封装Dapper,支持多种数据库类型.多库实例,简单强大: 此部分具体说明可参考博客: ...

随机推荐

  1. C#二维码生成

    C#二维码生成,这里使用开源的ThoughtWorks.QRCode.dll库. 1.下载ThoughtWorks.QRCode.dll库文件,并引用到项目中. 2.创建QRCodeHandler.c ...

  2. cralwer_爬虫代理中心的简要设计

    代理中心: 简单讲: 精细化控制限制资源的使用,保证有限资源的充分利用及有效性.支持动态增减,实时更新. 需求 rest api提供请求输入与输出 客户端使用代理心跳接收,用于更新代理的使用次数,被占 ...

  3. DirectX11 学习笔记3 - 创建一个立方体 和 轴

    该方案将在进一步的程序 面向对象. 独立的模型类.更像是一个框架. 其中以超过遇到了一个非常有趣的问题,.获得一晚.我读了好几遍,以找到其他的列子.必须放在某些功能Render里面实时更新,而不是仅仅 ...

  4. obj-c编程15[Cocoa实例03]:MVC以及归档化演示样例

    前面的博文里介绍了归档和解档,这里我们把它实际应用到一个简单的代码中去,将它作为一个多文档应用程序的打开和保存的背后支持.另外这里介绍一下MVC思想,这个在不论什么语言里都会有,它是一种设计思想,主要 ...

  5. 数据传输对象(DTO)介绍及各类型实体比较

    数据传输对象(DTO)介绍及各类型实体比较 本文将介绍DDD分层架构中广泛使用的数据传输对象Dto,并且与领域实体Entity,查询实体QueryObject,视图实体ViewModel等几种实体进行 ...

  6. firefox里面title乱码

    原文:firefox里面title乱码 昨天 在notepad++里面写得文档里面title里面有中文,即使在文档里面写有charset=’UTF-8’, 但是保存后在firefox运行,浏览器标签标 ...

  7. .Net IOC 之Unity

    .Net IOC 之Unity 在码农的世界里,为了应付时常变更的客户需求,增加的架构的客扩展性,减少工作量.IOC诞生了,它是一种可以实现依赖注入和控制对象生命周期的容器.最为一个有节操.有追求的码 ...

  8. [译]Java 垃圾回收的监控和分析

    说明:这篇文章来翻译来自于Javapapers 的Java Garbage Collection Monitoring and Analysi 在这个系列的Java垃圾回收教程中,我们将看到可用于垃圾 ...

  9. 删除指定表的所有索引,包括主键索引,唯一索引和普通索引 ,适用于sql server 2005,

    原文:删除指定表的所有索引,包括主键索引,唯一索引和普通索引 ,适用于sql server 2005, --删除指定表中所有索引 --用法:declare @tableName varchar(100 ...

  10. bat批量目光声明

    写bat同一批次,盯着函数应使用.这个程序对可读性 在批处理,凝视节还有一种更常用的方法: goto start      = 能够是多行文本,能够是命令      = 能够包括重定向符号和其它特殊字 ...