AOP的兩個應用:實體集更新(DateEntityListUpdate)、延遲加載(LazyLoad)(下)
LazyLoadableSink類
//*******************************************************************
// 模塊:實現延遲載入的消息接收器
// 日期:2009-9-19 14:08:58
// 作者:Faib
// 版權:Copyright Faib Studio 2009
// 官網:http://www.faib.Net.cn
// 郵箱:[email protected]
// 備注:
//*******************************************************************
using System;
using System.Reflection;
using System.Runtime.Remoting.Messaging;
using FaibClass.Data.Operation;
namespace FaibClass.Data.ASPect
{
/// <summary>
/// 實現延遲載入的消息接收器。
/// </summary>
internal class LazyLoadableSink : IMessageSink
{
private IMessageSink m_nextSink;
private MarshalByRefObject m_target;
private static object syncRoot = new object();
public LazyLoadableSink(MarshalByRefObject target, IMessageSink nextSink)
{
lock (syncRoot)
{
m_target = target;
m_nextSink = nextSink;
}
}
public IMessage SyncProcessMessage(IMessage msg)
{
IMethodReturnMessage returnedMessage;
HandleMessage(msg, false, out returnedMessage);
return returnedMessage;
}
public IMessageCtrl AsyncProcessMessage(IMessage msg, IMessageSink replySink)
{
IMethodReturnMessage returnedMessage;
HandleMessage(msg, true, out returnedMessage);
return m_nextSink.AsyncProcessMessage(msg, replySink);
}
public IMessageSink NextSink
{
get { return m_nextSink; }
}
/// <summary>
/// 處理消息
/// </summary>
/// <param name="msg"></param>
/// <param name="IsAsync"></param>
/// <param name="returnedMessage"></param>
private void HandleMessage(IMessage msg, bool IsAsync, out IMethodReturnMessage returnedMessage)
{
returnedMessage = null;
if (!IsAsync)
{
if (msg is IMethodCallMessage)
{
Type entityType = m_target.GetType();
IMethodCallMessage mcm = (IMethodCallMessage)msg;
bool isFill = (bool)entityType.GetProperty("InnerIsFill", BindingFlags.Instance | BindingFlags.NonPublic).GetValue(m_target, null);
//判斷是否獲取屬性或字段或是調用GetValue方法
bool isProperty = !isFill && ((mcm.MethodName.Length > 4 &&
mcm.MethodName.Substring(0, 4) == "get_" && mcm.MethodName != "get_InnerIsFill" &&
mcm.MethodName != "get_InnerDataState") || mcm.MethodName == "FIEldGetter" ||
mcm.MethodName == "GetValue");
object oldvalue = null;
MemberInfo minfo = null;
//屬性名字段名
string propertyName = string.Empty;
if (isProperty)
{
//字段
if (mcm.MethodName == "FIEldGetter")
propertyName = mcm.InArgs[1].ToString();
//GetValue方法
else if (mcm.MethodName == "GetValue")
propertyName = mcm.InArgs[0].ToString();
//屬性
else
propertyName = mcm.MethodName.Replace("get_", "");
minfo = Utility.GetMember(m_target.GetType(), propertyName);
if (minfo == null)
isProperty = false;
//判斷是否子實體集、引用實體、引用屬性
else if (!minfo.IsDefined(typeof(SubEntityListAttribute), true) &&
!minfo.IsDefined(typeof(ReferenceEntityAttribute), true) &&
!minfo.IsDefined(typeof(ReferencePropertyAttribute), true))
isProperty = false;
if (isProperty)
oldvalue = Utility.GetMemberValue(m_target, minfo, propertyName);
//值為空時才讀取數據庫
if (isProperty && oldvalue == null)
{
//取出緩存的操作對象
string key = DataCacheKeyManager.GetEntityInnerData(entityType);
object innerData = InnerCache<object[]>.Get(key);
if (innerData != null)
{
//構造一下操作對象
object[] _innerData = (object[])innerData;
DataHelper data = (DataHelper)Activator.CreateInstance((Type)_innerData[0]);
if (string.IsNullOrEmpty(data.ConnectionString))
data.ConnectionString = _innerData[1].ToString();
OperationArgs operArgs = new OperationArgs(data);
QueryBuilder query = new QueryBuilder(data.CreateParameters());
//子實體集
if (minfo.IsDefined(typeof(SubEntityListAttribute), true))
{
SubEntityListAttribute keyAttribute = DataMappingManager.GetSubEntityListKey(entityType, propertyName);
if (keyAttribute != null)
{
IDataEntityList list = (IDataEntityList)Activator.CreateInstance(keyAttribute.EntityListType);
Type refentityType = list.ModelType;
//取主鍵值
object value = ((DataEntity)m_target).GetValue(keyAttribute.PrimaryKey);
if (value != null)
{
//關聯關系
query.Append(QueryCompare.Equal, keyAttribute.ForeignKey, value);
if (!string.IsNullOrEmpty(keyAttribute.Condition))
{
query.Append(QueryRelation.And, keyAttribute.Condition);
}
//查詢實體集
list = SelectOperator.Select(Operargs, refentityType, query, null, null);
returnedMessage = new ReturnMessage(list, null, 0, null, mcm);
((DataEntity)m_target).SetValue(propertyName, returnedMessage.ReturnValue);
}
}
}
//引用實體
else if (minfo.IsDefined(typeof(ReferenceEntityAttribute), true))
{
ReferenceEntityAttribute keyAttribute = DataMappingManager.GetReferenceEntityKey(entityType, propertyName);
//取主鍵值
object value = ((DataEntity)m_target).GetValue(keyAttribute.ForeignKey);
if (value != null)
{
//關聯關系
query.Append(QueryCompare.Equal, keyAttribute.PrimaryKey, value);
object result = GetOperator.Get(Operargs, keyAttribute.ReferenceType, query, null, null);
returnedMessage = new ReturnMessage(result, null, 0, null, mcm);
((DataEntity)m_target).SetValue(propertyName, returnedMessage.ReturnValue);
}
}
//引用屬性
else if (minfo.IsDefined(typeof(ReferencePropertyAttribute), true))
{
ReferencePropertyAttribute keyAttribute = DataMappingManager.GetReferencePropertyKey(entityType, propertyName);
//取主鍵值
object value = ((DataEntity)m_target).GetValue(keyAttribute.ForeignKey);
if (value != null)
{
//關聯關系
query.Append(QueryCompare.Equal, keyAttribute.PrimaryKey, value);
DataEntity entity1 = GetOperator.Get(Operargs, keyAttribute.ReferenceType, query, null, null);
if (entity1 != null)
{
object result = entity1.GetValue((keyAttribute as ReferencePropertyAttribute).ReferencePropertyName);
returnedMessage = new ReturnMessage(result, null, 0, null, mcm);
((DataEntity)m_target).SetValue((keyAttribute as IKeyAttribute).Property, result);
}
}
}
data.Dispose();
}
}
}
}
if (returnedMessage == null)
returnedMessage = (IMethodReturnMessage)m_nextSink.SyncProcessMessage(msg);
}
else
{
returnedMessage = null;
}
}
}
}