Unity&Webform(2):自定义LifetimeManager和TypeConverter使Unity从HttpContext中取值注入WebForm页面...

2023-11-16

上一篇 Unity&WebForm(1): 自定义IHttpHandlerFactory使用Unity对ASP.NET Webform页面进行依赖注入中让Unity和WebForm结合在一起,通过使用HttpHandlerFactory实现了对页面的依赖注入,本文将在上篇的基础上,通过对Unity的LifetimeManager的扩展实现从WEB Application特有的HttpContext中取值注入页面

背景

在很多情况下,会有较为持久地保存对象的需求,但由于对象的类度太细,也许不会考虑使用数据库,此时HttpContext的Items属性是一个很好的归宿,而在某些页面,则需要从HttpContext中获得此类对象,一个比较普遍的做法是使用属性进行封装,代码如下
public  UserInfo CurrentUser
{
    
get
    
{
        
return HttpContext.Current.Items["CurrentUser"as UserInfo;
    }

    
set
    
{
        HttpContext.Current.Items[
"CurrentUser"= value;
    }

}
这样写的效果是显而易见的,避免了每一次接触CurrentUser都要写HttpContext.Current...之类的代码,但是就简洁性来说尚有不足,如果可以简单地写一个自动生成的属性,再由外界将HttpContext.Current.Items["CurrentUser"]注入其中,将会很大程度上提高程序编写的效率

原理

上一篇中已经将WebForm的页面和Unity合在了一起,在页面被创建之后即可由Unity对其进行注入,所以这次将在上一篇的基础上,通过扩展Unity实现功能。
在Unity中,如何获取对象的实例及如何销毁对象都是由LifetimeManager完成的,其定义如下
public   abstract   class  LifetimeManager : ILifetimePolicy, IBuilderPolicy
{
    
protected LifetimeManager();

    
public abstract object GetValue();
    
public abstract void RemoveValue();
    
public abstract void SetValue(object newValue);
}
其中GetValue方法获取对象实例,RemoveValue方法销毁对象,SetValue方法为对外引用的保存提供新的实例

有了这3个方法,就可以通过自定义LifetimeManager来实现从HttpContext中取值,但此处又会出现一个问题:
LifetimeManager如何得知需要取得的键值?
如果使用硬编码方式生成LifetimeManager的实例,那么在构造的时候传入键值即可,是十分方便的,但如果使用配置文件呢?

为了解决以上问题,就需要引入Unity中的另一个概念:TypeConverter
Unity为了解决在配置文件中写入值的问题,在定义Lifetime或者Property等参数的时候,会允许有一个typeConverter属性,Unity自动使用此属性中指出的继承自TypeConverter类的类实现字符串(保存于value属性)到具体对象的转换
因此,我们可以利用这一点,在value中保存需要的键值,再自定义TypeConverter生成LifetimeManager,也算是一个小小的Hack吧

实现

首先自定义一个LifetimeManager,在此叫ContextLifetimeManager,方法的实现非常简单,不多作解释,代码如下
public   class  ContextLifetimeManager : LifetimeManager
{
    
public string Key
    
{
        
get;
        
set;
    }


    
public ContextLifetimeManager(string key)
    
{
        Key 
= key;
    }


    
public override object GetValue()
    
{
        
return HttpContext.Current.Items[Key];
    }


    
public override void RemoveValue()
    
{
        HttpContext.Current.Items[Key] 
= null;
    }


    
public override void SetValue(object newValue)
    
{
        HttpContext.Current.Items[Key] 
= newValue;
    }

}
注意这只是最为简单的实现,没有考虑多线程同步等复杂的问题,也仅仅是作为一个演示,如果需要线程安全等特性,可以参考官方的ContainerControlledLifetimeManager(就是我们使用singleton作为生命周期时使用的),里面使用了Moniter控制线程同步

这里的问题便是如何将需要的Key传入到对象中,根据原理中说的,还需要一个TypeConverter,代码如下
public   class  ContextLifetimeManagerConverter : TypeConverter
{
    
public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
    
{
        
if (sourceType == typeof(string))
        
{
            
return true;
        }

        
return base.CanConvertFrom(context, sourceType);
    }


    
public override object ConvertFrom(ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value)
    
{
        
string str = value as string;
        
if (!String.IsNullOrEmpty(str))
        
{
            
return new ContextLifetimeManager(str);
        }

        
return base.ConvertFrom(context, culture, value);
    }

}
开发过web控件的人对这种写法会非常熟悉,和web控件中的属性赋值一样,重写2个方法将字符串转换为所需要的类型,在此像是构造一个新的ContextLifetimeManager对象并提供字符串值作为键值

在配置文件中,可以将value属性设为所需的键值,再提供此TypeConverter即可,我的配置文件如下
Code
<unity>
  
<typeAliases>
    
<typeAlias alias="singleton" type="Microsoft.Practices.Unity.ContainerControlledLifetimeManager, Microsoft.Practices.Unity"/>
    
<!-- 自定义的LifetimeManager的另名 -->
    
<typeAlias alias="context" type="GDev.Test.WebApp.Unity.ContextLifetimeManager, GDev.Test.WebApp"/>
  
</typeAliases>
  
<containers>
    
<container name="HttpHandlerContainer">
      
<types>
        
<type type="GDev.Test.WebApp.UserInfo, GDev.Test.WebApp" mapTo="GDev.Test.WebApp.UserInfo, GDev.Test.WebApp">
          
<!-- 使用自定义的ContextLifetimeManager,并利用typeConverter将key通过value传入 -->
          
<lifetime type="context"
                    value
="CurrentUser"
                    typeConverter
="GDev.Test.WebApp.Unity.ContextLifetimeManagerConverter, GDev.Test.WebApp" />
        
</type>
        
<!-- Default页面的依赖 -->
        
<type type="GDev.Test.WebApp.Default, GDev.Test.WebApp" mapTo="GDev.Test.WebApp.Default, GDev.Test.WebApp">
          
<lifetime type="singleton" />
          
<typeConfig extensionType="Microsoft.Practices.Unity.Configuration.TypeInjectionElement, Microsoft.Practices.Unity.Configuration">
            
<property name="CurrentUser" propertyType="GDev.Test.WebApp.UserInfo, GDev.Test.WebApp">
              
<dependency />
            
</property>
          
</typeConfig>
        
</type>
      
</types>
    
</container>
  
</containers>
</unity>
此处的键值为CurrentUser,向Default页面进行了注入

为了演示,修改Default页面的代码如下
public   partial   class  Default : System.Web.UI.Page
{
    
public UserInfo CurrentUser
    
{
        
get;
        
set;
    }


    
protected void Page_Load(object sender, EventArgs e)
    
{
        
if (CurrentUser != null)
        
{
            Response.Write(
"注入成功!");
        }

    }

}
在页面中有一个CurrentUser属性等待注入,其运行结果自然是显示了"注入成功",也就不再截图了

扩展

1.同样可以自定义SessionLifetimeManager,但需要注意的是不可以在HttpHandlerFactory中使用Session,因此要将BuildUp的时机放到页面的PreInit事件中,另外还需要注意的是,如果你将Unity和PIAB一起用,那么在页面的PreInit中使用container.BuildUp(GetType().BaseType, this);并无法提供PIAB的策略注入机制,其原因是PIAB的注入会返回一个全新的对象,而在些单纯地使用BuidUp仅仅是将this对象包装了起来
2.当然也可以有QueryStringLifetimeManager,不过这就更麻烦了,因为QueryString的值是string类型,要转换到其他类型还需要一个TypeConverter,一个可行的解决方案是在配置文件中的value项以一种约定的方式加入TypeConverter的类型,比如value="key&TypeConverterType"

总结

本文提供了对Unity的一种扩展的思路,本次扩展针对对象生命周期管理的环节,使其与WebForm更好地进行结合,事实上,如果愿意使用一个页面总基类并在页面的生命周期开始时再进行注入的话,还可以通过扩展BuilderExtension实现页面流程的控制,这将是下一次话题。

转载于:https://www.cnblogs.com/GrayZhang/archive/2008/06/11/1217228.html

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Unity&Webform(2):自定义LifetimeManager和TypeConverter使Unity从HttpContext中取值注入WebForm页面... 的相关文章

  • 天猫数据分析工具推荐(天猫第三方数据平台)

    在电商迅速发展的大背景下 做好天猫数据分析能够在多方面帮助品牌商家更好地运营店铺 塑造品牌 如通过数据分析了解消费者的需求 购买偏好 这有利于品牌商家及时调整商品结构 产品推广 商品宣传等等 灵活制定品牌的销售策略 那么 天猫平台行业 品牌
  • 广告竞价策略:激发广告变现潜能的关键

    在数字化时代 广告已经成为企业推广品牌 产品和服务的关键手段之一 为了最大程度地发挥广告的效果 广告竞价策略成为广告主和数字营销专业人士关注的焦点 通过巧妙运用竞价策略 广告主可以在激烈的市场竞争中脱颖而出 实现广告变现的潜能 admaoy
  • HarmonyOS鸿蒙开发指南:容器组建 stepper开发指导

    目录 创建Stepper组件 设置index属性 设置样式 添加事件 场景示例 创建Stepper组件 在pages index目录下的hml文件中创建一个Stepper组件 div class container div
  • 游戏被攻击了要怎么办

    有客户反馈刚上线新款游戏 没两天就被攻击了 导致用户无法登录 来咨询到我们这边能不能帮他解决 今天就来分享下 怎么预防游戏攻击和已经被攻击的游戏服务器该怎么处理 服务器不管是个人还是企业 被攻击的都有 在所难免 特别是新上线时候要承受住外来
  • HarmonyOS鸿蒙开发指南:容器组建 tabs开发指导

    目录 创建Tabs 设置Tabs方向 设置样式 显示页签索引 场景示例 创建Tabs 在pages index目录下的hml文件中创建一个Tabs组件 div class container div
  • 【Mysql】InnoDB 引擎中的页目录

    一 页目录和槽 现在知道记录在页中按照主键大小顺序串成了单链表 那么我使用主键查询的时候 最顺其自然的办法肯定是从第一条记录 也就是 Infrimum 记录开始 一直向后找 只要存在总会找到 这种在数据量少的时候还好说 一旦数据多了 遍历耗
  • 38条Web测试经验分享

    1 页面链接检查 每一个链接是否都有对应的页面 并且页面之间切换正确 可以使用一些工具 如LinkBotPro File AIDCS HTML Link Validater Xenu等工具 LinkBotPro不支持中文 中文字符显示为乱码
  • 图解python | 字符串及操作

    1 Python元组 Python的元组与列表类似 不同之处在于元组的元素不能修改 元组使用小括号 列表使用方括号 元组创建很简单 只需要在括号中添加元素 并使用逗号隔开即可 tup1 ByteDance ShowMeAI 1997 202
  • 基于java的饮食分享平台系统设计与实现

    基于java的饮食分享平台系统设计与实现 I 引言 A 研究背景和动机 近年来 随着人们生活水平的提高和健康意识的增强 饮食健康已经成为越来越多人的关注焦点 因此 一个方便快捷的饮食分享平台就显得尤为重要 基于Java的饮食分享平台系统设计
  • 【计算机毕业设计】白优校园社团网站的设计与实现

    近些年 随着中国经济发展 人民的生活质量逐渐提高 对网络的依赖性越来越高 通过网络处理的事务越来越多 随着白优校园社团网站的常态化 如果依然采用传统的管理方式 将会为工作人员带来庞大的工作量 这将是一个巨大考验 需要投入大量人力开展对社团
  • 【计算机毕业设计】springbootstone音乐播放器的设计与实现

    随着我国经济的高速发展与人们生活水平的日益提高 人们对生活质量的追求也多种多样 尤其在人们生活节奏不断加快的当下 人们更趋向于足不出户解决生活上的问题 stone音乐播放器展现了其蓬勃生命力和广阔的前景 与此同时 为解决用户需求 stone
  • 游戏开发常见操作梳理之小地图的制作

    游戏中一般存在小地图系统 实际上就是设置一个新的摄像机放置在玩家的正上方 然后在小地图上显示新摄像机看见的东西就可以了 在小地图上一般存在放大地图和缩小地图的按钮可以方便放大和缩小地图 这些操作是如何实现的呢 接下来直接上核心代码 usin
  • 游戏开发常用实践操作之按动任意键触发

    接下来一些笔记会对于一些大大小小的实践操作进行记录 希望对你有所帮助 在游戏中 我们经常会遇到一些按动任意键触发的操作 接下来展示核心代码 以下是对于Unity中的操作 使用的UI是NGUI 对于核心操作没有影响 你可以自己置换 void
  • 【计算机毕业设计】OA公文发文管理系统_xtv98

    近年来 人们的生活方式以网络为主题不断进化 OA公文发文管理就是其中的一部分 现在 无论是大型的还是小型的网站 都随处可见 不知不觉中已经成为我们生活中不可或缺的存在 随着社会的发展 除了对系统的需求外 我们还要促进经济发展 提高工作效率
  • Redis分布式锁--java实现

    文章目录 Redis分布式锁 方案 SETNX EXPIRE 基本原理 比较好的实现 会产生四个问题 几种解决原子性的方案
  • 毕业设计:基于python人脸识别系统 LBPH算法 sqlite数据库 (源码)✅

    博主介绍 全网粉丝10W 前互联网大厂软件研发 集结硕博英豪成立工作室 专注于计算机相关专业 毕业设计 项目实战6年之久 选择我们就是选择放心 选择安心毕业 感兴趣的可以先收藏起来 点赞 关注不迷路 毕业设计 2023 2024年计算机毕业
  • 温室气体排放更敏感的模型(即更高的平衡气候敏感性(ECS))在数年到数十年时间尺度上也具有更高的温度变化(Python代码实现)

    欢迎来到本博客 博主优势 博客内容尽量做到思维缜密 逻辑清晰 为了方便读者 座右铭 行百里者 半于九十 本文目录如下 目录 1 概述 2 运行结果 3 参考文献 4 Python代码 数据
  • UI自动化测试之Jenkins配置

    背景 团队下半年的目标之一是实现自动化测试 这里要吐槽一下 之前开发的测试平台了 最初的目的是用来做接口自动化测试和性能测试 但由于各种原因 接口自动化测试那部分功能整个废弃掉了 其中和易用性有很大关系 另外 也和我们公司的接口业务也有关
  • 一文从0到1手把手教学UI自动化测试之数据驱动!

    在UI的自动化测试中 我们需要把测试使用到的数据分离到文件中 如果单纯的写在我们的测试模块里面 不是一个好的设计 所以不管是什么类型的自动化测试 都是需要把数据分离出来的 当然分离到具体的文件里面 文件的形式其实有很多的 这里主要说明JSO
  • Python 使用 NoSQL 数据库的优选方案

    NoSQL 数据库因其高性能 可扩展性和灵活性而风靡一时 然而 对于 Python 程序员而言 选择合适的 NoSQL 数据库可能会令人困惑 因为有多种选择可供选择 那么 哪种 NoSQL 数据库最适合 Python 呢 2 解决方案 根据

随机推荐

  • 软件工程:(四)概要设计

    一 定义 概要设计是一个设计师根据用户交互过程和用户需求来形成交互框架和视觉框架的过程 其结果往往以反映交互控件布置 界面元素分组以及界面整体板式的页面框架图的形式来呈现 这是一个在用户研究和设计之间架起桥梁 使用户研究和设计无缝结合 将对
  • KNN实现手写数字识别

    其他实现手写数字识别的方法 1 聚类 K means 实现手写数字识别 2 卷积神经网络 CNN 实现手写数字识别 3 全连接神经网络实现手写数字识别 4 聚类 K means 实现手写数字识别 2 实验数据是老师收集了所有人的手写数字图片
  • jeesite快速开发平台(一)----简介

    以下内容来自官网 一 平台简介 JeeSite是基于多个优秀的开源项目 高度整合封装而成的高效 高性能 强安全性的开源Java EE快速开发平台 JeeSite是您快速完成项目的最佳基础平台解决方案 JeeSite是您想学习Java平台的最
  • 寄存器的基本原理

    参考大神博客 https blog csdn net qq 37340753 article details 80935423 https blog csdn net u012493828 article details 53439226
  • kali工具的使用

    一 netcat简介与使用 nc的全称为NetCat 它能够建立并接受传输控制协议 TCP 和用户数据报协议 UDP 的连接 Netcat可在这些连接上读写数据 直到连接关闭为止 它可以通过手工或者脚本与应用层的网络应用程序或服务进行交互
  • openblas 第二弹: openblas Android版调用和编译

    1 编译 如果需要在Android下使用openblas 则需要编译Android版本的openblas a文件进行调用 1 openblas的编译时主要参考链接 参考链接一 参考链接二 具体细节太久了 已经忘了 下面是编译好的时候的环境变
  • Linux中普通用户和ROOT用户对Java JDK的配置

    Linux中对对各种工具文件不需要想Windows中似的 还要先一步一步的安装 有的还需要配置环境变量 比如Windows对Java的安装过程 在Linux中 使用指令 tar zxvf 文件名 注意空格 解压完 tar gz 文件 或使用
  • Spring事务实现原理

    Spring事务的原理是基于AOP实现的 所以流程也可以理解为与AOP一样分为3步 解析切面 织入通知和运行时增强 1 解析切面 Srping事务的是通过 EnableTransactionManagement注解开启的 该注解往IoC容器
  • 【逆向】使用CE查找Android中变量的偏移

    0x00 准备工作下载Cheat Engine以及调试器服务端 https www cheatengine org index php 夜神模拟器 https www yeshen com 下载安装贪婪洞窟 梦境模式 http a 4399
  • 【华为OD机试】路灯照明问题 (C++ Python Java)2023 B卷

    时间限制 C C 1秒 其他语言 2秒 空间限制 C C 262144K 其他语言524288K 64bit IO Format lld 题目描述 在一条笔直的公路上安装了N个路灯 从位置0开始安装 路灯之间间距固定为100米 每个路灯都有
  • oracle修改块大小设置,oracle性能调整(1)

    1调整数据库服务器的性能Oracle数据库服务器是整个系统的核心 它的性能高低直接影响整个系统的性能 为了调整Oracle数据库服务器的性能 主要从以下几个方面考虑 1 1Oracle 调整操作系统以适合Oracle数据库服务器运行数据库服
  • 利用PicGo+Gitee配置图床

    引言 配置图床 方便我们的使用 比如 我们利用typora写的笔记 直接把发送给别人也可以正常使用 不再会有由于本地图片 而加载不出来图片的情况 此外 图片文件遗失亦可以正常加载出来 因为图片已上传 这里已 Typora Gitee Pic
  • java String(一)—— Java中的String类型

    一 需要理解的代码 import java lang reflect Array import java util ArrayList import java util Arrays import java util HashMap imp
  • DNS服务器正向/反向解析配置

    第四次作业 题目 配置DNS正反向解析 一 正向解析 1 装包 2 配置服务 3 配置服务器 4 测试 1 yum install bind y 2 vim etc named conf 监听53号端口 访问的是本机ip 129 168 2
  • c++命名空间

    命名空间 主要解决全局变量的冲突 内部不允许私有变量 所有变量都是公有的 namespace data int x 10 data x 为域作用符 直接使用等同于使用全局变量 不存在就是0 不包含匿名命名空间内变量 同一个文件引用stati
  • 相见恨晚的办公插件合集(二)

    之前有分享过一些办公的插件 如不坑盒子 打工人插件 易用宝等 下面就简单的介绍一下上面的几个神器后再补充一些其它办公神器吧 不坑盒子 word wps 这是一个非常好用的插件工具 专门应用在Word文档和wps 支持Office 2010以
  • 拓数派入选中国信通院 “铸基计划”「高质量数字化转型产品及服务全景图」

    7 月 27 日 由中国信息通信研究院 以下简称 中国信通院 主办的 2023 数字生态发展大会 暨中国信通院 铸基计划 年中会议在京召开 本次大会深度展示了中国信通院在数字化领域的工作成果 并正式发布了 高质量数字化转型产品及服务全景图
  • GUI基础知识

    GUI编程 1 简介 图形用户界面 Graphical User Interface 又称图形用户接口 是指采用图形方式显示的计算机操作用户界面 GUI的核心技术 AWT Swing 2 Awt 2 1 AWT简介 AWT Abstract
  • springboot报错Could not autowire. No beans of ‘RedisConnectionFactory‘ type found

    这个报错提示是因为springboot升级到2 6 9以后版本就会出现 报错界面 其实上面报错不影响程序使用 但是总是觉得别扭 提供3种解决方式 第一种方案 springboot版本降到2 6 9或以下 第二种方案 通过idea设置不提示该
  • Unity&Webform(2):自定义LifetimeManager和TypeConverter使Unity从HttpContext中取值注入WebForm页面...

    上一篇 Unity WebForm 1 自定义IHttpHandlerFactory使用Unity对ASP NET Webform页面进行依赖注入中让Unity和WebForm结合在一起 通过使用HttpHandlerFactory实现了对