网络上总是能看到,如果离开某某框架,代价有多大多大。或者对某某框架进行封装,降低框架变更的风险与成本。
最近的项目用到了Nhibernate做数据访问,于是也想用东西给它封装下。不过对一个一个的业务实体,都创建一个类,实在是太麻烦了。于是就想到了使用模板类,这样即可以达到封装的目的,编码量也不会很大。
首先对创建一个抽象类
public
abstract
class
ActionBase
... {
public ActionBase()
...{
}
internal ActionBase(ISession session)
...{
this.session = session;
}
private ISession session;
protected ISession Session
...{
get
...{
if (session == null)
session = Config.SessionFactory.OpenSession();
return session;
}
set
...{
this.session = value;
}
}
public void Flush()
...{
Session.Flush();
}
}
... {
public ActionBase()
...{
}
internal ActionBase(ISession session)
...{
this.session = session;
}
private ISession session;
protected ISession Session
...{
get
...{
if (session == null)
session = Config.SessionFactory.OpenSession();
return session;
}
set
...{
this.session = value;
}
}
public void Flush()
...{
Session.Flush();
}
}
然后创建Template类,对ISession对象的操作进行封装
public
class
ActionTemplate
<
T
>
: ActionBase
... {
public ActionTemplate()
...{
}
internal ActionTemplate(ISession session)
: base(session)
...{
}
public virtual void Save(T obj)
...{
Session.Save(obj);
}
public virtual void Update(T obj)
...{
Session.Update(obj);
}
public virtual void Delete(T obj)
...{
Session.Delete(obj);
}
public virtual T Get(object id)
...{
return Session.Get<T>(id);
}
public virtual T Load(object id)
...{
return Session.Load<T>(id);
}
public virtual void SaveOrUpdate(T obj)
...{
Session.SaveOrUpdate(obj);
}
public virtual IList<T> List()
...{
IQuery query = Session.CreateQuery("from " + typeof(T).ToString());
return query.List<T>();
}
public virtual CriteriaTemplate<T> CreateCriteria()
...{
return new CriteriaTemplate<T>(this.Session);
}
... {
public ActionTemplate()
...{
}
internal ActionTemplate(ISession session)
: base(session)
...{
}
public virtual void Save(T obj)
...{
Session.Save(obj);
}
public virtual void Update(T obj)
...{
Session.Update(obj);
}
public virtual void Delete(T obj)
...{
Session.Delete(obj);
}
public virtual T Get(object id)
...{
return Session.Get<T>(id);
}
public virtual T Load(object id)
...{
return Session.Load<T>(id);
}
public virtual void SaveOrUpdate(T obj)
...{
Session.SaveOrUpdate(obj);
}
public virtual IList<T> List()
...{
IQuery query = Session.CreateQuery("from " + typeof(T).ToString());
return query.List<T>();
}
public virtual CriteriaTemplate<T> CreateCriteria()
...{
return new CriteriaTemplate<T>(this.Session);
}
使用另一个模板类,对查询对象进行封装
public
class
CriteriaTemplate
<
T
>
... {
private CriteriaTemplate()
...{
ObjectType = typeof(T);
}
internal CriteriaTemplate(ISession session)
: this()
...{
this.Criteria = session.CreateCriteria(typeof(T));
}
private ICriteria Criteria;
private Type ObjectType;
private bool isChanged = true;
private IList<T> returnList;
public void AddExpression(string propertyName, object value, ExpressionType type)
...{
if (value == null)
throw new ArgumentNullException("value", "值不能为空。");
PropertyInfo property = CheckProperty(propertyName);
if (type == ExpressionType.In && !(value is object[]))
...{
throw new ArgumentException("value", "当使用In操作时,参数必须为数组。");
}
else if (property.PropertyType != value.GetType())
...{
throw new ArgumentException("value", "Value值类型于参数类型不一致。");
}
switch (type)
...{
case ExpressionType.Eq:
Criteria = Criteria.Add(Expression.Eq(propertyName, value));
break;
case ExpressionType.Ge:
Criteria = Criteria.Add(Expression.Ge(propertyName, value));
break;
case ExpressionType.Great:
Criteria = Criteria.Add(Expression.Gt(propertyName, value));
break;
case ExpressionType.In:
Criteria = Criteria.Add(Expression.In(propertyName, value as object[]));
break;
case ExpressionType.Less:
Criteria = Criteria.Add(Expression.Lt(propertyName, value));
break;
case ExpressionType.Like:
Criteria = Criteria.Add(Expression.Like(propertyName, value));
break;
case ExpressionType.Le:
Criteria = Criteria.Add(Expression.Le(propertyName, value));
break;
case ExpressionType.NotEq:
Criteria = Criteria.Add(Expression.Not(Expression.Eq(propertyName, value)));
break;
default:
throw new DataAccessException("不支持的操作类型!");
}
isChanged = true;
}
private PropertyInfo CheckProperty(string propertyName)
...{
PropertyInfo property = ObjectType.GetProperty(propertyName);
if (property == null)
throw new DataAccessException("未找到指定属性。");
return property;
}
public void IsNull(string propertyName)
...{
CheckProperty(propertyName);
Criteria.Add(Expression.IsNull(propertyName));
isChanged = true;
}
public void IsNotNull(string propertyName)
...{
CheckProperty(propertyName);
Criteria.Add(Expression.IsNotNull(propertyName));
isChanged = true;
}
public IList<T> List()
...{
if (isChanged)
...{
returnList = Criteria.List<T>();
}
return returnList;
}
... {
private CriteriaTemplate()
...{
ObjectType = typeof(T);
}
internal CriteriaTemplate(ISession session)
: this()
...{
this.Criteria = session.CreateCriteria(typeof(T));
}
private ICriteria Criteria;
private Type ObjectType;
private bool isChanged = true;
private IList<T> returnList;
public void AddExpression(string propertyName, object value, ExpressionType type)
...{
if (value == null)
throw new ArgumentNullException("value", "值不能为空。");
PropertyInfo property = CheckProperty(propertyName);
if (type == ExpressionType.In && !(value is object[]))
...{
throw new ArgumentException("value", "当使用In操作时,参数必须为数组。");
}
else if (property.PropertyType != value.GetType())
...{
throw new ArgumentException("value", "Value值类型于参数类型不一致。");
}
switch (type)
...{
case ExpressionType.Eq:
Criteria = Criteria.Add(Expression.Eq(propertyName, value));
break;
case ExpressionType.Ge:
Criteria = Criteria.Add(Expression.Ge(propertyName, value));
break;
case ExpressionType.Great:
Criteria = Criteria.Add(Expression.Gt(propertyName, value));
break;
case ExpressionType.In:
Criteria = Criteria.Add(Expression.In(propertyName, value as object[]));
break;
case ExpressionType.Less:
Criteria = Criteria.Add(Expression.Lt(propertyName, value));
break;
case ExpressionType.Like:
Criteria = Criteria.Add(Expression.Like(propertyName, value));
break;
case ExpressionType.Le:
Criteria = Criteria.Add(Expression.Le(propertyName, value));
break;
case ExpressionType.NotEq:
Criteria = Criteria.Add(Expression.Not(Expression.Eq(propertyName, value)));
break;
default:
throw new DataAccessException("不支持的操作类型!");
}
isChanged = true;
}
private PropertyInfo CheckProperty(string propertyName)
...{
PropertyInfo property = ObjectType.GetProperty(propertyName);
if (property == null)
throw new DataAccessException("未找到指定属性。");
return property;
}
public void IsNull(string propertyName)
...{
CheckProperty(propertyName);
Criteria.Add(Expression.IsNull(propertyName));
isChanged = true;
}
public void IsNotNull(string propertyName)
...{
CheckProperty(propertyName);
Criteria.Add(Expression.IsNotNull(propertyName));
isChanged = true;
}
public IList<T> List()
...{
if (isChanged)
...{
returnList = Criteria.List<T>();
}
return returnList;
}
如果某一个对象,在保存的时候需要特殊的操作,可以建立一个继承自模板的类,然后重写模板类中的一些方法
public
class
OrderAction : ActionTemplate
<
Order
>
... {
public OrderAction(ISession session) : base(session) ...{}
public override void Save(Order order)
...{
//do same thing
base.Save(order)
}
}
... {
public OrderAction(ISession session) : base(session) ...{}
public override void Save(Order order)
...{
//do same thing
base.Save(order)
}
}
最后使用一个管理类,对各个数据访问对象进行管理
public
class
ActionManager : ActionBase, IDisposable
... {
public ActionManager()
...{
Session = ConfigFactiry.CreateSession();
}
private ActionTemplate<SameObj> sameAction;
private ActionTemplate<Same2Obj> same2Action;
private OrderAction orderAction;
public ActionTemplate<SameObj> SameAction
...{
get
...{
if (sameAction == null)
sameAction = new ActionTemplate<SameObj>(this.Session);
return sameAction;
}
}
public ActionTemplate<Same2Obj> Same2Action
...{
get
...{
if (same2Action == null)
same2Action = new ActionTemplate<Same2Obj>(this.Session);
return same2Action;
}
}
public OrderAction OrderAction
...{
get
...{
if (orderAction == null)
orderAction = new OrderAction(this.Session);
return orderAction;
}
}
IDisposable 成员#region IDisposable 成员
public void Dispose()
...{
//Session.Flush();
Session.Close();
Session.Dispose();
}
#endregion
}
... {
public ActionManager()
...{
Session = ConfigFactiry.CreateSession();
}
private ActionTemplate<SameObj> sameAction;
private ActionTemplate<Same2Obj> same2Action;
private OrderAction orderAction;
public ActionTemplate<SameObj> SameAction
...{
get
...{
if (sameAction == null)
sameAction = new ActionTemplate<SameObj>(this.Session);
return sameAction;
}
}
public ActionTemplate<Same2Obj> Same2Action
...{
get
...{
if (same2Action == null)
same2Action = new ActionTemplate<Same2Obj>(this.Session);
return same2Action;
}
}
public OrderAction OrderAction
...{
get
...{
if (orderAction == null)
orderAction = new OrderAction(this.Session);
return orderAction;
}
}
IDisposable 成员#region IDisposable 成员
public void Dispose()
...{
//Session.Flush();
Session.Close();
Session.Dispose();
}
#endregion
}
这样就实现了对NHibernate的简单封装,可以在项目中简单方便的使用了。