经过了上篇IRepositoryIRepository<T>的讨论【文章地址为:http://www.cnblogs.com/yomho/p/3296759.html

我选择了IRepository作为我重构框架的仓储接口

一、接口定义  

新的IRepository接口设计如下:

  1. namespace Yom.NFramework2_0
  2. {
  3. public interface IRepository<TCompositeKey>
  4. where TCompositeKey : IEquatable<string>
  5. {
  6. #region 实体操作接口
  7. T FindBy<T>(TCompositeKey primaryKey) where T : IEntity;
  8. IEnumerable<T> FindAll<T>() where T : IEntity;
  9. IEnumerable<T> FindAll<T>(IWhere[] where) where T : IEntity;
  10. IEnumerable<T> FindAll<T>(IWhere[] where, IOrder[] order) where T : IEntity;
  11. IEnumerable<T> FindAll<T>(int pageIndex, int pageSize, IWhere[] where, IOrder[] order, out int count) where T : IEntity;
  12. void Add<T>(T entity) where T : IEntity;
  13. void Delete<T>(T entity) where T : IEntity;
  14. void DeleteAll<T>() where T : IEntity;
  15. void DeleteAll<T>(IWhere[] where) where T : IEntity;
  16. void DeleteAll<T>(string where) where T : IEntity;
  17. void DeleteAll<T>(IEnumerable<TCompositeKey> pkValues) where T : IEntity;
  18. void Update<T>(T entity) where T : IEntity;
  19. bool Exists<T>(TCompositeKey primaryKey) where T : IEntity;
  20. #endregion
  21. #region 静态方法接口
  22. int ExecuteSql(string sql, params System.Data.IDataParameter[] ps);
  23. object ExecuteScalar(string sql, params System.Data.IDataParameter[] ps);
  24. System.Data.DataTable ExecuteDataTable(string sql, params System.Data.IDataParameter[] ps);
  25. #endregion
  26. }
  27. }

其中IEntity和IWhere以及IOrder的设计接口如下:

  1. public interface IEntity
  2. {
  3. }
  4. public interface IOrder
  5. {
  6. }
  7. public interface IWhere
  8. {
  9. }
  10. public interface ICompositeKey : IEquatable<string>
  11. {
  12. }

ICompositeKey为组合主键接口

为什么ICompositeKey要继承为IEquatable<string>这个接口呢?

因为IEquatable<string>是string的基类,且string为不能继承的类,

所以目的是和string兼容,经过处理可以变成一个string类,从而可以兼容普通的非组合主键。

(此文不讲组合主键的实现原理,展示组合主键接口只是让大家看看组合主键实现解耦的方法)

二、嫁接Castle实现搜索以及排序

很多人不知道怎么把自己的IRepository接口的排序和搜索对象解耦,

在用不同的ORM实现IRepository接口的时候总不知道怎么弄排序和搜索

下面就来看我怎么把Castle的排序和搜索用IOrder以及IWhere解耦的

首先是IOrder -> NHibernate.Expression.Order 的变身

  1. namespace Yom.NFramework2_0.CastleExtend
  2. {
  3. public class OrderBase : NHibernate.Expression.Order, Yom.NFramework2_0.IOrder
  4. {
  5. public OrderBase(string propertyName, bool ascending) : base(propertyName, ascending) {
  6.  
  7. }
  8. }
  9. }

这个很简单,OrderBase一下子就变成了NHibernate.Expression.Order

那么IWhere是否可以顺利完成像IOrder这种变身么?

研究后发现:Castle是用NHibernate.Expression.Expression的静态方法创建查询对象的

静态方法都是返回NHibernate.Expression.AbstractCriterion抽象类或者ICriterion接口

可以继承这个抽象对象或者接口吧,这样就可以实现变身了!!!

但如果真要这样做,必然有抽象方法要实现,这实在是一个下下策(想嫁接个接口和抽象类不容易吖)

那有没有直接实现NHibernate.Expression.AbstractCriterion抽象类的类呢?

反正我是没有找到,但是Castle肯定有,如果找到这么个类,就可以像IOrder一样实现嫁接,现在没有发现只能想他法。

最后我对WhereBase的变身是:

  1. namespace Yom.NFramework2_0.CastleExtend
  2. {
  3. public class WhereBase : Yom.NFramework2_0.IWhere
  4. {
  5. public NHibernate.Expression.ICriterion Instance
  6. {
  7. get;
  8. set;
  9. }
  10. public override string ToString()
  11. {
  12. return Instance.ToString();
  13. }
  14. #region 废弃代码
  15. //public static void AllEq(WhereBase where, System.Collections.IDictionary propertyNameValues)
  16. //{
  17. // where.Instance = NHibernate.Expression.Expression.AllEq(propertyNameValues);
  18. //}
  19. //public static void And(WhereBase where, WhereBase whereA, WhereBase whereB)
  20. //{
  21. // where.Instance = NHibernate.Expression.Expression.And(whereA.Instance, whereB.Instance);
  22. //}
  23. //public static void Between(WhereBase where, string propertyName, object lo, object hi)
  24. //{
  25. // where.Instance = NHibernate.Expression.Expression.Between(propertyName, lo, hi);
  26. //}
  27. //public static void Eq(WhereBase where, string propertyName, object value) {
  28. // where.Instance = NHibernate.Expression.Expression.Eq(propertyName, value);
  29. //}
  30. //public static void EqProperty(WhereBase where, string propertyName, string otherPropertyName)
  31. //{
  32. // where.Instance = NHibernate.Expression.Expression.EqProperty(propertyName, otherPropertyName);
  33. //}
  34. //public static void Ge(WhereBase where, string propertyName, object value)
  35. //{
  36. // where.Instance = NHibernate.Expression.Expression.Ge(propertyName, value);
  37. //}
  38. //public static void GeProperty(WhereBase where, string propertyName, string otherPropertyName)
  39. //{
  40. // where.Instance = NHibernate.Expression.Expression.GeProperty(propertyName, otherPropertyName);
  41. //}
  42. //public static void Gt(WhereBase where, string propertyName, object value)
  43. //{
  44. // where.Instance = NHibernate.Expression.Expression.Gt(propertyName, value);
  45. //}
  46. //public static void GtProperty(WhereBase where, string propertyName, string otherPropertyName)
  47. //{
  48. // where.Instance = NHibernate.Expression.Expression.GtProperty(propertyName, otherPropertyName);
  49. //}
  50. //public static void IdEq(WhereBase where, object value)
  51. //{
  52. // where.Instance = NHibernate.Expression.Expression.IdEq(value);
  53. //}
  54. //public static void In(WhereBase where, string propertyName, System.Collections.ICollection values)
  55. //{
  56. // where.Instance = NHibernate.Expression.Expression.In(propertyName, values);
  57. //}
  58. //public static void InG<T>(WhereBase where, string propertyName, ICollection<T> values)
  59. //{
  60. // where.Instance = NHibernate.Expression.Expression.InG<T>(propertyName, values);
  61. //}
  62. //public static void InsensitiveLike(WhereBase where, string propertyName, object value)
  63. //{
  64. // where.Instance = NHibernate.Expression.Expression.InsensitiveLike(propertyName, value);
  65. //}
  66. //public static void IsEmpty(WhereBase where, string propertyName)
  67. //{
  68. // where.Instance = NHibernate.Expression.Expression.IsEmpty(propertyName);
  69. //}
  70. //public static void propertyName(WhereBase where, string propertyName)
  71. //{
  72. // where.Instance = NHibernate.Expression.Expression.IsNotEmpty(propertyName);
  73. //}
  74. //public static void IsNotNull(WhereBase where, string propertyName)
  75. //{
  76. // where.Instance = NHibernate.Expression.Expression.IsNotNull(propertyName);
  77. //}
  78. //public static void IsNull(WhereBase where, string propertyName)
  79. //{
  80. // where.Instance = NHibernate.Expression.Expression.IsNull(propertyName);
  81. //}
  82. //public static void Le(WhereBase where, string propertyName, object value)
  83. //{
  84. // where.Instance = NHibernate.Expression.Expression.Le(propertyName, value);
  85. //}
  86. //public static void LeProperty(WhereBase where, string propertyName, string otherPropertyName)
  87. //{
  88. // where.Instance = NHibernate.Expression.Expression.LeProperty(propertyName, otherPropertyName);
  89. //}
  90. //public static void Like(WhereBase where, string propertyName, string value, NHibernate.Expression.MatchMode matchModes)
  91. //{
  92. // where.Instance = NHibernate.Expression.Expression.Like(propertyName, value, matchModes);
  93. //}
  94.  
  95. //public static void Lt(WhereBase where, string propertyName, object value)
  96. //{
  97. // where.Instance = NHibernate.Expression.Expression.Lt(propertyName, value);
  98. //}
  99. //public static void LtProperty(WhereBase where, string propertyName, string otherPropertyName)
  100. //{
  101. // where.Instance = NHibernate.Expression.Expression.LtProperty(propertyName, otherPropertyName);
  102. //}
  103. //public static void Not(WhereBase where)
  104. //{
  105. // where.Instance = NHibernate.Expression.Expression.Not(where.Instance);
  106. //}
  107. //public static void NotEqProperty(WhereBase where, string propertyName, string otherPropertyName)
  108. //{
  109. // where.Instance = NHibernate.Expression.Expression.NotEqProperty(propertyName, otherPropertyName);
  110. //}
  111. //public static void Or(WhereBase where, WhereBase whereA, WhereBase whereB)
  112. //{
  113. // where.Instance = NHibernate.Expression.Expression.Or(whereA.Instance, whereB.Instance);
  114. //}
  115. //public static void Sql(WhereBase where, string sql)
  116. //{
  117. // where.Instance = NHibernate.Expression.Expression.Sql(sql);
  118. //}
  119. #endregion
  120. }
  121. }

最好注释也去掉,这样的好处是别人开发的可以不管ORM是用什么第三方框架,直接调用WhereBase静态方法(代理模式)

WhereBase直接携带了Castle的搜索接口ICriterion,

在RepositoryBase有个这么个方法转换IWhere为Castle的搜索对象

  1. #region 其他方法
  2. NHibernate.Expression.ICriterion[] IWhere2ICriterion(IWhere[] where)
  3. {
  4. if (where == null) {
  5. return null;
  6. }
  7. NHibernate.Expression.ICriterion[] wheres = new NHibernate.Expression.ICriterion[where.Length];
  8. for (var i = ; i < where.Length; i++)
  9. {
  10. wheres[i] = (where[i] as WhereBase).Instance;
  11. }
  12. return wheres;
  13. }
  14. #endregion

这样就可以完美地实现搜索和排序的解耦

仓储基类有个方法实现如下:

  1. public IEnumerable<T> FindAll<T>(IWhere[] where) where T : IEntity
  2. {
  3. if (where == null) {
  4. return FindAll<T>();
  5. }
  6. return Castle.ActiveRecord.ActiveRecordBase<T>.FindAll(IWhere2ICriterion(where));
  7. }

三、总结:    

1:搜索和排序的解耦不算是个难题

2: 实现的仓储基类可以通过IoC注入实例化,这样可以插拔式更换ORM

3: 定义的仓储接口和实现最好放在不同的类库,以更好的解耦

四、后记:Repository实现仓储--Castle实现      

  1. namespace Yom.NFramework2_0.CastleExtend
  2. {
  3. public abstract class EntityBase : Castle.ActiveRecord.ActiveRecordBase, Yom.NFramework2_0.IEntity
  4. {
  5. }
  6. }

实体基类嫁接

  1. namespace Yom.NFramework2_0
  2. {
  3. public interface ISinglePrimaryKeyRepository : IRepository<string>
  4. {
  5. }
  6. }

非组合主键仓储扩展

  1. namespace Yom.NFramework2_0.CastleExtend
  2. {
  3. public class CastleSinglePrimaryKeyRepository : ISinglePrimaryKeyRepository//, System.Configuration.IConfigurationSectionHandler
  4. {
  5. #region IRepository<string> 成员
  6.  
  7. #region 实体相关操作
  8. public T FindBy<T>(string primaryKey) where T : IEntity
  9. {
  10. return Castle.ActiveRecord.ActiveRecordBase<T>.Find(primaryKey);
  11. }
  12.  
  13. public IEnumerable<T> FindAll<T>() where T : IEntity
  14. {
  15. return Castle.ActiveRecord.ActiveRecordBase<T>.FindAll();
  16. }
  17.  
  18. public IEnumerable<T> FindAll<T>(IWhere[] where) where T : IEntity
  19. {
  20. if (where == null) {
  21. return FindAll<T>();
  22. }
  23. return Castle.ActiveRecord.ActiveRecordBase<T>.FindAll(IWhere2ICriterion(where));
  24. }
  25.  
  26. public IEnumerable<T> FindAll<T>(IWhere[] where, IOrder[] order) where T : IEntity
  27. {
  28. if (order == null)
  29. {
  30. if (where == null)
  31. {
  32. return Castle.ActiveRecord.ActiveRecordBase<T>.FindAll();
  33. }
  34. else
  35. {
  36. return Castle.ActiveRecord.ActiveRecordBase<T>.FindAll(IWhere2ICriterion(where));
  37. }
  38. }
  39. else if (where == null)
  40. {
  41. return Castle.ActiveRecord.ActiveRecordBase<T>.FindAll(order as NHibernate.Expression.Order[]);
  42. }
  43.  
  44. return Castle.ActiveRecord.ActiveRecordBase<T>.FindAll(order as NHibernate.Expression.Order[], IWhere2ICriterion(where));
  45. }
  46.  
  47. public IEnumerable<T> FindAll<T>(int pageIndex, int pageSize, IWhere[] where, IOrder[] order, out int count) where T : IEntity
  48. {
  49. if (where == null)
  50. {
  51. count = Castle.ActiveRecord.ActiveRecordMediator.Count(typeof(T));
  52. if (order == null) {
  53. return Castle.ActiveRecord.ActiveRecordBase<T>.SlicedFindAll(pageIndex * pageSize, pageSize);
  54.  
  55. }else{
  56. return Castle.ActiveRecord.ActiveRecordBase<T>.SlicedFindAll(pageIndex * pageSize, pageSize, order as NHibernate.Expression.Order[]);
  57. }
  58. }
  59. else
  60. {
  61. count = Castle.ActiveRecord.ActiveRecordMediator.Count(typeof(T), IWhere2ICriterion(where));
  62. if (order == null) {
  63. return Castle.ActiveRecord.ActiveRecordBase<T>.SlicedFindAll(pageIndex * pageSize, pageSize, IWhere2ICriterion(where));
  64. }
  65. }
  66. return Castle.ActiveRecord.ActiveRecordBase<T>.SlicedFindAll(pageIndex * pageSize, pageSize, order as NHibernate.Expression.Order[], IWhere2ICriterion(where));
  67. }
  68.  
  69. public void Add<T>(T entity) where T : IEntity
  70. {
  71. using (Castle.ActiveRecord.TransactionScope tran = new Castle.ActiveRecord.TransactionScope())
  72. {
  73. (entity as Castle.ActiveRecord.ActiveRecordBase).CreateAndFlush();
  74. tran.VoteCommit();
  75. }
  76. }
  77.  
  78. public void Delete<T>(T entity) where T : IEntity
  79. {
  80. using (Castle.ActiveRecord.TransactionScope tran = new Castle.ActiveRecord.TransactionScope())
  81. {
  82. (entity as Castle.ActiveRecord.ActiveRecordBase).DeleteAndFlush();
  83. tran.VoteCommit();
  84. }
  85. }
  86.  
  87. public void DeleteAll<T>() where T : IEntity
  88. {
  89. using (Castle.ActiveRecord.TransactionScope tran = new Castle.ActiveRecord.TransactionScope())
  90. {
  91. Castle.ActiveRecord.ActiveRecordBase<T>.DeleteAll();
  92. tran.VoteCommit();
  93. }
  94. }
  95.  
  96. public void DeleteAll<T>(IWhere[] where) where T : IEntity
  97. {
  98. IEnumerable<T> entities;
  99. if (where == null)
  100. {
  101. entities = this.FindAll<T>();
  102. }
  103. else
  104. {
  105. entities = this.FindAll<T>(where);
  106. }
  107. if (entities != null)
  108. {
  109. using (Castle.ActiveRecord.TransactionScope tran = new Castle.ActiveRecord.TransactionScope())
  110. {
  111. foreach (T entity in entities) {
  112. this.Delete<T>(entity);
  113. }
  114. tran.VoteCommit();
  115. }
  116. }
  117. }
  118. public void DeleteAll<T>(string where) where T : IEntity
  119. {
  120.  
  121. using (Castle.ActiveRecord.TransactionScope tran = new Castle.ActiveRecord.TransactionScope())
  122. {
  123. Castle.ActiveRecord.ActiveRecordBase<T>.DeleteAll(where);
  124. tran.VoteCommit();
  125. }
  126.  
  127. }
  128. public void DeleteAll<T>(IEnumerable<string> pkValues) where T : IEntity
  129. {
  130. using (Castle.ActiveRecord.TransactionScope tran = new Castle.ActiveRecord.TransactionScope())
  131. {
  132. Castle.ActiveRecord.ActiveRecordBase<T>.DeleteAll(pkValues);
  133. tran.VoteCommit();
  134. }
  135. }
  136.  
  137. public void Update<T>(T entity) where T : IEntity
  138. {
  139. using (Castle.ActiveRecord.TransactionScope tran = new Castle.ActiveRecord.TransactionScope())
  140. {
  141. (entity as Castle.ActiveRecord.ActiveRecordBase).UpdateAndFlush();
  142. tran.VoteCommit();
  143. }
  144. }
  145.  
  146. public bool Exists<T>(string primaryKey) where T : IEntity
  147. {
  148. return Castle.ActiveRecord.ActiveRecordBase<T>.Exists<string>(primaryKey);
  149. }
  150. #endregion
  151. #region ado执行sql
  152. public int ExecuteSql(string sql, params System.Data.IDataParameter[] ps)
  153. {
  154. using (System.Data.IDbCommand cmd = Castle.ActiveRecord.ActiveRecordMediator.GetSessionFactoryHolder().CreateSession(typeof(CastleSinglePrimaryKeyRepository)).Connection.CreateCommand())
  155. {
  156. cmd.CommandText = sql;
  157. if (ps != null && ps.Length > )
  158. {
  159. foreach (System.Data.IDataParameter p in ps)
  160. {
  161. cmd.Parameters.Add(p);
  162. }
  163. }
  164. return cmd.ExecuteNonQuery();
  165. }
  166. }
  167.  
  168. public object ExecuteScalar(string sql, params System.Data.IDataParameter[] ps)
  169. {
  170. using (System.Data.IDbCommand cmd = Castle.ActiveRecord.ActiveRecordMediator.GetSessionFactoryHolder().CreateSession(typeof(CastleSinglePrimaryKeyRepository)).Connection.CreateCommand())
  171. {
  172. cmd.CommandText = sql;
  173. if (ps != null && ps.Length > )
  174. {
  175. foreach (System.Data.IDataParameter p in ps)
  176. {
  177. cmd.Parameters.Add(p);
  178. }
  179. }
  180. return cmd.ExecuteScalar();
  181. }
  182. }
  183.  
  184. public System.Data.DataTable ExecuteDataTable(string sql, params System.Data.IDataParameter[] ps)
  185. {
  186. using (System.Data.IDbCommand cmd = Castle.ActiveRecord.ActiveRecordMediator.GetSessionFactoryHolder().CreateSession(typeof(CastleSinglePrimaryKeyRepository)).Connection.CreateCommand())
  187. {
  188. cmd.CommandText = sql;
  189. if (ps != null && ps.Length > )
  190. {
  191. foreach (System.Data.IDataParameter p in ps)
  192. {
  193. cmd.Parameters.Add(p);
  194. }
  195. }
  196. System.Data.DataTable result = new System.Data.DataTable();
  197. result.Load(cmd.ExecuteReader(System.Data.CommandBehavior.CloseConnection));
  198. return result;
  199. }
  200. }
  201. #endregion
  202. #endregion
  203. #region 其他方法
  204. NHibernate.Expression.ICriterion[] IWhere2ICriterion(IWhere[] where)
  205. {
  206. if (where == null) {
  207. return null;
  208. }
  209. NHibernate.Expression.ICriterion[] wheres = new NHibernate.Expression.ICriterion[where.Length];
  210. for (var i = ; i < where.Length; i++)
  211. {
  212. wheres[i] = (where[i] as WhereBase).Instance;
  213. }
  214. return wheres;
  215. }
  216. #endregion
  217. }
  218. }

Castle实现IReposoitory

五、项目开发的层次结构                                                                                              

【Yom框架】漫谈个人框架的设计之二:新的IRepository接口+搜索和排序解耦(+基于Castle实现)的更多相关文章

  1. JAVA经常使用集合框架使用方法具体解释基础篇二之Colletion子接口List

    接着上一篇,接着讲讲集合的知识.上一篇讲了Collection接口.它能够说是集合的祖先了,我们这一篇就说说它的子孙们. 一.Collection的子接口 List:有序(存入和取出的顺序一致).元素 ...

  2. 【Yom框架】漫谈个人框架的设计之一:是IRepository还是IRepository<T>?

    前言                                                                                                   ...

  3. 基于ZedBoard的Webcam设计(一):USB摄像头(V4L2接口)的图片采集【转】

    转自:http://www.cnblogs.com/surpassal/archive/2012/12/19/zed_webcam_lab1.html 一直想把USB摄像头接到Zedboard上,搭建 ...

  4. 【Yom框架】漫谈个人框架的设计之三:业务接口+UI层的设计(基于Castle实现的Repository)

    Repository层设计的文章见:[http://www.cnblogs.com/yomho/p/3297042.html]   一.概要设计 上面Reposity 应该为 Repository 特 ...

  5. 从MVC框架看MVC架构的设计

    尽管MVC早已不是什么新鲜话题了,但是从近些年一些优秀MVC框架的设计上,我们还是会发现MVC在架构设计上的一些新亮点.本文将对传统MVC架构中的一些弊病进行解读,了解一些优秀MVC框架是如何化解这些 ...

  6. 从MVC框架看MVC架构的设计(转)

    尽管MVC早已不是什么新鲜话题了,但是从近些年一些优秀MVC框架的设计上,我们还是会发现MVC在架构设计上的一些新亮点.本文将对传统MVC架构中的一些弊病进行解读,了解一些优秀MVC框架是如何化解这些 ...

  7. 基于SSH框架的考勤管理系统的设计与实现

    基于SSH框架的考勤管理系统的设计与实现

  8. 基于python的接口测试框架设计(二)配置一些参数及文件

    基于python的接口测试框架设计(二)配置一些参数及文件 我这里需要基于我的项目配置的主要是登陆参数.以及baseURL ,把这些放在单独的文件里  毕竟导入的时候方便了一些 首先是url 图略 建 ...

  9. 好的框架需要好的 API 设计 —— API 设计的六个原则

    说到框架设计,打心底都会觉得很大很宽泛,而 API 设计是框架设计中的重要组成部分.相比于有很多大佬都认可的面向对象的六大原则.23 种常见的设计模式来说,API 设计确实缺少行业公认的原则或者说设计 ...

随机推荐

  1. Android_显示器本身被卸载应用程序

    1.经jni实现功能 //LOG宏定义 #define LOG_INFO(tag, msg) __android_log_write(ANDROID_LOG_INFO, tag, msg) #defi ...

  2. 64bit Centos6.4编hadoop-2.5.1

    64bit Centos6.4编hadoop-2.5.1   1.说明 a)       因为从apache下载下来的tar.gz包是用32 bit编译的,全部假设用Linux 64作为hadoop的 ...

  3. MySQL 升级方法指南大全

    原文:MySQL 升级方法指南大全 通常,从一个发布版本升级到另一个版本时,我们建议按照顺序来升级版本.例如,想要升级 MySQL 3.23 时,先升级到 MySQL 4.0,而不是直接升级到 MyS ...

  4. IOS中TableView的使用(1) -创建一个简单的tableView

    创建一个简单的tableView: #import <UIKit/UIKit.h> /*tableView 一定要遵守这两个协议: UITableViewDataSource,UITabl ...

  5. ZOJ 2675 Little Mammoth(计算几何)

    圆形与矩形截面的面积 三角仍然可以做到这一点 代码: #include<stdio.h> #include<string.h> #include<stdlib.h> ...

  6. 一步一步写算法(之prim算法 中)

    原文:一步一步写算法(之prim算法 中) [ 声明:版权所有,欢迎转载,请勿用于商业用途.  联系信箱:feixiaoxing @163.com] C)编写最小生成树,涉及创建.挑选和添加过程 MI ...

  7. 使用Row_Number()分页优化

    记一次SQLServer的分页优化兼谈谈使用Row_Number()分页存在的问题   最近有项目反应,在服务器CPU使用较高的时候,我们的事件查询页面非常的慢,查询几条记录竟然要4分钟甚至更长,而且 ...

  8. 探秘ReSharper8.1版本中Architecture(架构工具)的改进

    在ReSharper 8.0新版本中,有一个叫做Architecture(结构工具)的新功能,此功能被定义为项目依赖关系分析.其目的是让用户可视化操作解决方案的结构.接下来,小编将在ReSharper ...

  9. 安装Windows2003操作系统 - 初学者系列 - 学习者系列文章

    Windows 2003是一款经典的服务器操作系统.以前笔者工作的时候就是用的这款操作系统来进行编程的.下面就对该操作系统的安装进行介绍(部分步骤参见XP的安装http://www.cnblogs.c ...

  10. Web前端框架与类库

    Web前端框架与类库的思考 说起前端框架,我也是醉了.现在去面试或者和同行聊天,动不动就这个框架碉堡了,那个框架好犀利. 当然不是贬低框架,只是有一种杀鸡焉用牛刀的感觉.网站技术是为业务而存在的,除此 ...