码迷,mamicode.com
首页 > Windows程序 > 详细

架构搭建----基于DDD领域驱动设计的WCF+EF+WPF分层框架(2)

时间:2016-04-09 12:17:04      阅读:394      评论:0      收藏:0      [点我收藏+]

标签:

写在最前面:转载请注明出处

目录置顶:

架构搭建

架构是基于DDD领域驱动模型的,DDD的思想我就不介绍了,园里有挺多的介绍了,另外在下面的架构图里面也会有体现,架构图本应该用UML图展示一下的,我觉得麻烦,我直接把我的项目截一个图介绍一下:

技术分享

项目我分了四个解决方案文件夹:ACS.OA.Common、ACS.OA.UIClient、ACS.OA.WCFServer、ACS.OA.WebSite(这个本次博客不打算介绍,直接忽略)。

ACS.OA.Common

这个文件夹里面我建了Base、Global、Model、WCFContract四个项目,这四个项目大家看名称就知道作用了。

Base的内部结构我也截一张图吧

技术分享技术分享

这个重点在CS文件夹里面,Cache缓存类,Communication通讯类,CustomException 异常处理类,Lib帮助集合(比较多,我把截图放旁边了),Log日志类(Log4Net)

我重点讲一下通讯类Pactet数据包

技术分享
 1    /// <summary>
 2    /// 打包、解包
 3    /// </summary>
 4    /// <typeparam name="T">数据类型 object</typeparam>
 5     public abstract class Packet<T>
 6     {        
 7         /// <summary>
 8         /// 打包数据
 9         /// </summary>
10         /// <param name="t"></param>
11         /// <param name="strKey">加密Key</param>
12         /// <returns></returns>
13         public static byte[] PacketData(T t, string strKey)
14         {
15             var jSetting = new JsonSerializerSettings();
16             jSetting.NullValueHandling = NullValueHandling.Ignore;      //忽略为NULL的值
17 
18             byte[] bytContent;
19             string strJson = JsonConvert.SerializeObject(t, jSetting);  //T转Json
20             strJson = DESHelper.Encrypt(strJson, strKey);               //加密
21             bytContent = SerializeHelper.Serialize(strJson);            //压缩转byte[]
22 
23             Init(bytContent);
24             return bytContent;
25         }
26 
27         /// <summary>
28         /// 解包数据
29         /// </summary>
30         /// <param name="bytContent"></param>
31         /// <param name="strKey">解密Key</param>
32         /// <returns></returns>
33         public static T DePacketData(byte[] bytContent, string strKey)
34         {
35             var jSetting = new JsonSerializerSettings();
36             jSetting.NullValueHandling = NullValueHandling.Ignore;                       //忽略为NULL的值
37 
38             T t;
39             string strJson = SerializeHelper.Deserialize(bytContent).ToString();         //解压缩转string
40             strJson = DESHelper.Decrypt(strJson, strKey);                                //解密
41             t = (T)JsonConvert.DeserializeObject(strJson, typeof(T), jSetting);           //Json转T
42             return t;
43         }
44 
45     }
View Code

里面的DESHelper的加密解密方法用的是TripleDESCryptoServiceProvider,需要的话自己引用一下就可以自己写了,这个实例比较多,我就不贴代码了。

我说一下我为何这么做的原因

打包步骤:

我先把实体类转为Json字符串目的为统一传输规则,这样做不用考虑发送方和接收方是什么语言开发的,接收方收到json解析就行了。

我又把Json串加密,这是为了安全考虑,数据传输用明文不安全吧。

转byte[] 压缩一下,文件会小很多,考虑的是传输效率。

解包步骤 就是打包的逆向了,不解释了啊。

 Lib帮助类集合里面,我讲一下WCFHandler类,先贴代码

技术分享
  1     public class WCFHandler
  2     {
  3         public static T CreateHttpServiceClient<T>(string webAddress, string serviceName)
  4         {
  5             T t = default(T);
  6             object obj = Activator.CreateInstance(typeof(T), new object[]
  7             {
  8                 GetHttpBinding(),
  9                 GetEndpoint(webAddress, serviceName)
 10             });
 11             t = (T)(obj);
 12             return t;
 13         }
 14 
 15         public static T CreateTcpServiceClient<T>(string webAddress, string serviceName, bool isStream=false)
 16         {
 17             T t = default(T);
 18             object obj;
 19             if (isStream) //流传输
 20             {
 21                 obj = Activator.CreateInstance(typeof(T), new object[]
 22                 {
 23                     GetFileTcpBinding(),
 24                     GetEndpoint(webAddress, serviceName)
 25                 });
 26             }
 27             else         //缓存传输
 28             {
 29                 obj = Activator.CreateInstance(typeof(T), new object[]
 30                 {
 31                     GetTcpBinding(),
 32                     GetEndpoint(webAddress, serviceName)
 33                 });
 34             }
 35             t = (T)(obj);
 36             return t;
 37         }
 38         
 39         public static NetTcpBinding GetTcpBinding()
 40         {
 41             return new NetTcpBinding
 42             {
 43                 MaxBufferPoolSize = 2147483646L,
 44                 MaxReceivedMessageSize = 2147483646L,
 45                 CloseTimeout = new TimeSpan(0, 0, 10),
 46                 OpenTimeout = new TimeSpan(0, 0, 10),
 47                 ReceiveTimeout = TimeSpan.MaxValue,
 48                 SendTimeout = new TimeSpan(0, 20, 0),
 49                 ReaderQuotas =
 50                 {
 51                     MaxDepth=64,
 52                     MaxStringContentLength=2147483646,
 53                     MaxArrayLength=2147483646,
 54                     MaxBytesPerRead=2147483646,
 55                     MaxNameTableCharCount=2147483646
 56                 },
 57                 ReliableSession =
 58                 {
 59                     Enabled = true,
 60                     Ordered = true,
 61                     InactivityTimeout = new TimeSpan(0, 0, 10)
 62                 },
 63                 Security =
 64                 {
 65                     Mode=SecurityMode.None,
 66                     Message =
 67                     {
 68                         ClientCredentialType = System.ServiceModel.MessageCredentialType.Windows
 69                     },
 70                     Transport =
 71                     {
 72                         ClientCredentialType =  TcpClientCredentialType.Windows
 73                     }
 74                 },
 75 
 76             };
 77         }
 78 
 79 
 80         /// <summary>
 81         /// TCP大文件断点续传
 82         /// </summary>
 83         /// <returns></returns>
 84         public static NetTcpBinding GetFileTcpBinding()
 85         {
 86             return new NetTcpBinding
 87             {
 88                 MaxBufferPoolSize = 2147483646L,
 89                 MaxReceivedMessageSize = 2147483646L,
 90                 CloseTimeout = new TimeSpan(0, 0, 10),
 91                 OpenTimeout = new TimeSpan(0, 0, 10),
 92                 ReceiveTimeout = TimeSpan.MaxValue,
 93                 SendTimeout = new TimeSpan(0, 20, 0),
 94                 TransferMode=TransferMode.Streamed,
 95                 ReaderQuotas =
 96                 {
 97                     MaxDepth=64,
 98                     MaxStringContentLength=2147483646,
 99                     MaxArrayLength=2147483646,
100                     MaxBytesPerRead=2147483646,
101                     MaxNameTableCharCount=2147483646
102                 },
103                 //ReliableSession =
104                 //{
105                 //    Enabled = true,
106                 //    Ordered = true,
107                 //    InactivityTimeout = new TimeSpan(1, 0, 0)
108                 //},
109                 //Security =
110                 //{
111                 //    Mode=SecurityMode.None,
112                 //    Message =
113                 //    {
114                 //        ClientCredentialType = System.ServiceModel.MessageCredentialType.Windows
115                 //    },
116                 //    Transport =
117                 //    {
118                 //        ClientCredentialType =  TcpClientCredentialType.Windows
119                 //    }
120                 //},
121 
122             };
123         }
124 
125         public static WSHttpBinding GetHttpBinding()
126         {
127             return new WSHttpBinding
128             {
129                 MaxBufferPoolSize = 2147483646L,
130                 MaxReceivedMessageSize = 2147483646L,
131                 CloseTimeout = new TimeSpan(0, 0, 10),
132                 OpenTimeout = new TimeSpan(0, 0, 10),
133                 ReceiveTimeout = new TimeSpan(0, 20, 0),
134                 SendTimeout = new TimeSpan(0, 20, 0),
135                 ReliableSession =
136                 {
137                     Enabled = true,
138                     Ordered = true,
139                     InactivityTimeout = new TimeSpan(0, 0, 10)
140                 },
141                 UseDefaultWebProxy = false,
142                 Security =
143                 {
144                     Mode = SecurityMode.None,
145                     Message =
146                     {
147                         ClientCredentialType = System.ServiceModel.MessageCredentialType.Windows
148                     },
149                     Transport =
150                     {
151                         ClientCredentialType = System.ServiceModel.HttpClientCredentialType.Windows
152                     }
153                 },
154             };
155         }
156         public static EndpointAddress GetEndpoint(string webAddress, string serviceName)
157         {
158             Uri uri = new Uri(webAddress + "/" + serviceName + ".svc");
159             return new EndpointAddress(uri, new AddressHeader[0]);
160         }
161 
162         public static EndpointAddress GetIMEndpoint(string webAddress, string serviceName)
163         {
164             Uri uri = new Uri(webAddress + "/" + serviceName + ".svc");
165             return new EndpointAddress(uri, new AddressHeader[0]);
166         }
167     }
View Code

这个里面是NET.TCP 和WSHttp 的WCF配置,这个类主要用于客户端的 需要传入两个参数“webAddress”,“serviceName”

webaddress我的做法是配置在客户端的App.Config读取。

serviceName我是根据每一个不同方法手工写入的

我再贴一下用法实例

 1        /// <summary>
 2         /// 艾克仕网络云OA企业名片
 3         /// </summary>
 4         public FirmCardPacket GetFirmCard(FirmCardPacket packet)
 5         {
 6             using (SettingServiceClient client = CreateTcpServiceClient<SettingServiceClient>(Caches.GolbalCache.WCFAddressCache, "MainClient/SettingService"))
 7             {
 8                 client.Open();
 9                 byte[] bt = null;
10                 bt = Packet<FirmCardPacket>.PacketData(packet, strKey);
11                 bt = client.GetFirmCard(bt);
12                 packet = Packet<FirmCardPacket>.DePacketData(bt, strKey);
13                 client.Close();
14             }
15             return packet;
16         }

这个现在就展示一下用法,到我把WCF代理讲完,在UI里面我详细讲。


Base主要的是这些了,下面讲Global

先贴图

技术分享

 Global项目就是它的字面意思,全局的信息或者配置就放在这里。这个不用多讲了,大家如果使用我这套架构的话,如何划分全局还得靠自己,每个项目一般都不一样的。


下面是Model

 技术分享技术分享

Model我的文件夹分类规则是一个客户端项目对应一个Model文件夹,多个客户端公用的在Common文件夹,Base文件夹是基类举一个例子说明基类的用法

WPF需要实时刷新界面数据的话,我的实体如IMinfo就会继承Notify。IMpacket是具体的数据包需要继承PacketModel。

PacketModel里面是一些公共属性,LoginId,FirmId,ResultCode,ResultMsg 这些信息。

我贴一下Notify的代码

 1 public abstract class Notify : INotifyPropertyChanged
 2     {
 3         public event PropertyChangedEventHandler PropertyChanged;
 4 
 5         protected virtual bool SetProperty<T>(ref T storage, T value, [CallerMemberName] string propertyName = null)
 6         {
 7             if (object.Equals(storage, value)) return false;
 8 
 9             storage = value;
10             this.OnPropertyChanged(propertyName);
11 
12             return true;
13         }
14 
15         protected void OnPropertyChanged(string propertyName)
16         {
17             var eventHandler = this.PropertyChanged;
18             if (eventHandler != null)
19             {
20                 eventHandler(this, new PropertyChangedEventArgs(propertyName));
21             }
22         }        
23     }

这个代码不解释了,做WPF的都知道。


ACS.OA.WCFContract

 WCF契约,我为何要写在这里呢?是因为我是使用SvcUtil生成的WCF代理类,这个代理类和WCF服务库都公用这个契约,代理类和服务库的代码就会很简洁了,而且可以保证代理类和服务库的方法一致。

契约不用贴图,WCF有明确规定的,等到即时通讯需要双工的地方我会贴特定的契约接口。

 

到此,ACS.OA.Common解决方案文件夹讲完,下面讲ACS.OA.WCFServer,不要走开,精彩还在后面

ACS.OA.WCFServer

 

<p><span style="font-size: 16px;"><strong><span style="color: #ff0000;"><a href="http://www.cnblogs.com/acssoft/p/5370286.html"><span style="color: #ff0000;">写在最前面:转载请注明出处</span></a></span></strong></span></p>

架构搭建----基于DDD领域驱动设计的WCF+EF+WPF分层框架(2)

标签:

原文地址:http://www.cnblogs.com/acssoft/p/5370388.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!