65.9K
CodeProject 正在变化。 阅读更多。
Home

抽象、缓存和共享 WURFL

emptyStarIconemptyStarIconemptyStarIconemptyStarIconemptyStarIcon

0/5 (0投票)

2009 年 2 月 9 日

CPOL

4分钟阅读

viewsIcon

20991

downloadIcon

92

ASP.NET 中简单易用的移动设备功能查询。

下载解决方案

WURFL2_file_sequence2.png

引言

在上一篇文章(WURFL ASP.NET 实现)中,我比较了 3 个 ASP.NET WURFL 库,用于查询移动设备的功能。本文将选取其中一个性能最好的实现(WURFL.Marg),并为其创建一个包装类。该库(类)公开了一致的高层对象,创建了一个对象层次结构(而不是扁平的字符串集合),缓存对象并依赖于数据文件,并将此数据跨多个 Web 应用程序共享。

背景

决定创建包装类而不是扩展现有源文件是基于松耦合的考虑。

  • 如果 WURFL.Marg 的源文件被维护开发人员修改,只要所使用的方法签名未被更改,此包装类仍应能正常工作,只需稍作修改。
  • 该包装类不特定于实现——如果选择 WURFL.Marg 以外的其他 WURFL 库,切换将非常简单。

共享数据文件似乎不是什么大问题,是吗?嗯,有好有坏。WURFL.Marg 开箱即支持此功能,但缓存功能不支持。一旦提供了依赖项中心缓存,就需要特别考虑数据文件(WURFL.xml - 设备功能数据)的共享位置。

缓存本身并不复杂——需要考虑对象层次结构,并且在数据文件修改时需要重新加载缓存。这通过 System.Web.Caching.Cache 类实现,为 WURFL.xml 文件设置 CacheDependency 对象,并使用 CacheItemRemovedCallback 类通过延迟事件在数据文件修改后重新加载缓存。

包装类与上一篇文章中对三个 WURFL 实现应用的指标相同。测试步骤是:

  1. 用户代理:当前设备
    功能:mobile_browser
    数据已修改:false
  2. 用户代理:当前设备
    功能:xhtml_table_support
    数据已修改:false
  3. 用户代理:当前设备
    功能:ajax_support_javascript
    数据已修改:false
  4. 用户代理:当前设备
    功能:resolution_width
    数据已修改:false
  5. 用户代理:NokiaN92-2
    功能:mobile_browser
    数据已修改:false
  6. 用户代理:NokiaN92-2
    功能:xhtml_table_support
    数据已修改:false
  7. 用户代理:NokiaN92-2
    功能:ajax_support_javascript
    数据已修改:false
  8. 用户代理:NokiaN92-2
    功能:resolution_width
    数据已修改:false
  9. 用户代理:iPhone
    功能:mobile_browser
    数据已修改:true

结果如下:

WURFL2_metrics_600x97.png

包装类已在具有强类型功能层次结构(包括智能感知)和不带这些属性的情况下进行了测试。差异微乎其微;强类型功能并未带来性能损失。测试 #1 和 #5 中的差异可归因于缓存已加载,这值得“一次性的开销”。明显的差异出现在测试 #9——这是一个理想的结果。这表明当数据文件在服务器上被修改时,缓存被重新加载;这在之前测试过的任何 WURFL 实现中都没有发生。

下图显示了功能层次结构和支持的智能感知

WURFL2_intellisense2.png

使用代码

WURFL.Margemx.tcp.mobile 都会被使用,并且需要将它们添加为 Web 应用程序/网站项目的引用。log4net 将作为依赖项(WURFL.Marg 的依赖项)添加到 bin 文件夹,不需要作为引用。

web.config 文件将需要下面列出的 WURFL.Marg 的基本编辑

WURFL2_web_config.png

log4netbrowserCaps 部分是可选的。

共享方法的使用非常简单。使用原始的扁平集合和强类型对象查询当前设备的功能是:

// flat WurflDeviceIndex collection
Response.Write(
emx.tcp.mobile.Device.currentDevice()
.capabilities["resolution_height"].value + "<br/>");


// strongly typed equivilent object
Response.Write(
emx.tcp.mobile.Device.currentDevice()
.display.resolutionHeight + "<br/>");

使用原始的扁平集合和强类型对象查询推荐设备(带用户代理)的功能是:

// flat WurflDeviceIndex collection
Response.Write(
emx.tcp.mobile.Device.referredDevice("NokiaN92-2")
.capabilities["resolution_height"].value + "<br/>");


// strongly typed equivilent object
Response.Write(
emx.tcp.mobile.Device.referredDevice("NokiaN92-2")
.display.resolutionHeight + "<br/>");

所有缓存和对象实例化都在后台执行——简单易用...

关注点

不幸的是,referredDevice 对象具有完整的缓存/依赖项感知功能,而 currentDevice 则没有。currentDevice 的实例化(间接)以用户代理作为参数——因此,实际上,它只在会话期间有效。因此,currentDevice 被存储在 Session 字典中。已添加一个新方法(loadCurrentCache),可以从 SessionStart 事件调用。

未来的增强

我正在为当前项目添加一些日志记录(用户代理、应用程序等)代码,并打算从中挖掘数据,缓存和索引最常用的用户代理——如果这个过程足够模块化,我会将其添加到这个库中...

历史

  • 2009-02-09 - currentDevice 存储在 Session 字典中
  • 2009-02-07 - 文章提交
© . All rights reserved.