AOP的两个应用(下)

AOP的两个应用:实体集更新(DateEntityListUpdate)、延迟加载(LazyLoad)(下)

LazyLoadableSink类

//*******************************************************************
    // 模块:实现延迟载入的消息接收器
    // 日期:2009-9-19 14:08:58
    // 作者:Faib
    // 版权:Copyright Faib Studio 2009
    // 官网:http://www.faib.net.cn
    // 邮箱:faib920@126.com
    // 备注:
    //*******************************************************************
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;
    }
    }
    }
    }

时间: 2024-11-02 23:49:20

AOP的两个应用(下)的相关文章

利用ASP嵌套JS+SQL Server打造两级连动下拉框(一)

js|server|下拉 利用ASP嵌套JS+SQL Server打造两级连动下拉框(1)   随着网络技术的迅速发展,越来越多的电子商务网站也应运而生.而在构建一个功能强大的电子商务网站往往少不了提供网上注册功能给客户自行注册这个模块,为了尽可能方便客户填写信息,我们经常要用到下拉框供客户选择,特别是两级连动下拉框最为常用. 再说,本人今日发现CSDN论坛上也经常有网友提问这个问题,就是,需要一个两级连动下拉框,第一个显示省份名称,第二个显示相应的城市名.为了解答这个问题,我特别写这篇文章,希

利用ASP嵌套JS+SQL Server打造两级连动下拉框(二)

js|server|下拉 利用ASP嵌套JS+SQL Server打造两级连动下拉框(2) TwoLevel.asp<html><head><meta http-equiv="Content-Type" content="text/html; charset=gb2312"><meta name="GENERATOR" content="Microsoft FrontPage 4.0"

利用ASP嵌套JS+SQL Server打造两级连动下拉框

js|server|sql|下拉 随着网络技术的迅速发展,越来越多的电子商务网站也应运而生.而在构建一个功能强大的电子商务网站往往少不了提供网上注册功能给客户自行注册这个模块,为了尽可能方便客户填写信息,我们经常要用到下拉框供客户选择,特别是两级连动下拉框最为常用. 再说,本人今日发现CSDN论坛上也经常有网友提问这个问题,就是,需要一个两级连动下拉框,第一个显示省份名称,第二个显示相应的城市名.为了解答这个问题,我特别写这篇文章,希望能对需要这方面资料的网友有所帮助. 首先,我们先来设计数据库

AOP的两个应用(上)

AOP的两个应用:实体集更新(DateEntityListUpdate).延迟加载(LazyLoad)(上) 在FaibClass.Data中,有两个AOP的应用,它们分别是实体集更新(DateEntityListUpdate).延迟加载 (LazyLoad),目前的DataEntity继承于ContextBoundObject,刚刚从网上看到ContextBoundObject的损耗非常大,但自己测试了一下,应该说影响不是很大,所以暂时不打算使用静态注入了. 注,两个AOP都采用Attribu

sql查询两级分类下数据

问题描述 sql查询两级分类下数据 sql 怎么用select查询两级分类下的所有的数据...... 解决方案 有key对应吗,如果有可以用join去连接查询 解决方案二: SQL 查询某属性分类数据和SQL distinct 分类查询----------------------

请问excel中导出的数据如何分为垂直的两排向下排列,不要一列排列,怎么实现?

问题描述 请问excel中导出的数据如何分为垂直的两排向下排列,不要一列排列,怎么实现? 请问excel中导出的数据如何分为垂直的两排向下排列,不要一列排列,怎么实现? 解决方案 http://jingyan.baidu.com/article/9faa72315d6bd5473c28cbe9.html

静态成员变量,是不是在①该变量在被引用时 ②所在类被实例化时 这两种情况下会被实例化?

问题描述 静态成员变量,是不是在:①该静态成员变量在被引用时②所在类被实例化时这两种情况下会被初始化? 解决方案 解决方案二:静态成员变量一加载就存在,无需实例化解决方案三:引用1楼xuzuning的回复: 静态成员变量一加载就存在,无需实例化 你好,我说的是被赋初值(初始化)的问题,一被加载就有初始值了,还是该静态成员变量在被引用时或所在类被实例化时才被赋初始值??

javascrpit-请问代码在两种环境下执行不一样啊?

问题描述 请问代码在两种环境下执行不一样啊? 原意是在DW中图片可以在页面中切换,而在chrome中就变成直接跳转到图片了,页面就不存在了. 关键代码如下: function showPic(whichpic) { var source = whichpic.getAttribute("href"); var placeholder = document.getElementById("placeholder"); var text = whichpic.getAt

两种Linux下非交互式命令的实现

一.概述 在Linux环境,有多种实现自动化的脚本语言,如Shell.Python.Perl.Tcl等.Shell语言因与Shell外壳结合紧密,是最常见的实现自动化的脚本语言. 同时,在Linux环境中存在大量功能单一的小工具--通常它们在指定输入后,立即就可获得输出,例如echo.cat等字符串/文本打印工具,又或者是如sed.awk等最常用的字符串编辑工具.通过编写Shell脚本,我们可以反复利用这些小工具来实现一些自动化的批处理. 在少数情况下,我们也需要用到一些交互式的工具,例如pas