网络上总是能看到,如果离开某某框架,代价有多大多大。或者对某某框架进行封装,降低框架变更的风险与成本。
最近的项目用到了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();
}

}
然后创建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
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;
}
如果某一个对象,在保存的时候需要特殊的操作,可以建立一个继承自模板的类,然后重写模板类中的一些方法
public
class
OrderAction : ActionTemplate
<
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
}
这样就实现了对NHibernate的简单封装,可以在项目中简单方便的使用了。