现在的位置: 首页 > 综合 > 正文

PetShop4的状态管理之不完全理解

2013年07月23日 ⁄ 综合 ⁄ 共 5362字 ⁄ 字号 评论关闭
Petshop4中的用户状态管理实在令人费解,MS那班天才就不能设计更清晰的类来维护用户状态吗?
如果初学的朋友也像我一样看了半天没有头绪,又找不到参考资料,在这里希望我个人对关于状态管理的部分理解会对你有所启发。

SettingsProperty  名称标识符+如何读写对象的描述,这些描述定义存取SettingsPropertyValue对象的方式。
                                是否将状态对象持久化,以及如何持久化。对应配置文件里两行。
SettingsPropertyCollection  元素类型是SettingsProperty的集合,通常作为参数传递。
SettingsPropertyValue pv = new SettingsPropertyValue(SettingsProperty); 
                              需要关联一个SettingsProperty对象,描述了如何访问状态对象pv.PropertyValue。
                              pv.PropertyValue是我们真正关心的实例对象,需要实时维护的用户状态信息。
                               pv.Property  返回状态对象访问策略描述SettingsProperty,如:购物车对象是PetShop.BLL.Cart
                                                     类,用指定的自定义引擎读写,即时保存到数据库,需要时从数据库读取。
                              pv.Property.Name  配置文件中对应的标识符,如:"ShoppingCart"
                              pv.PropertyValue    内存中真正需要维护的状态对象,如:购物车对象user.Cart。
SettingsPropertyValueCollection  元素类型为SettingsPropertyValue的对象集合,通常作为参数传递。

用户访问网站时,应用程序后台服务需要记录用户的活动状态,用一个Profile实例,代替Session可以持久化到配置文件(数据库)中,也可以扩展需要记录的状态信息。
PetShop中自定义了类ProfileCommon。
ProfileCommon    承于ProfileBase,继承于Properties,继承于SettingsBase
从ProfileBase继承了以下成员:
SettingsPropertyCollection Properties;   //PropertyValues读写策略
SettingsPropertyValueCollection PropertyValues;   //状态信息中需要维护(读写)的实例集合
SettingsContext Context;    //当前用户及应用程序信息
从ProfileBase继承了以下方法:
public object GetPropertyValue(string propertyName);   //可能从文件或数据库中读取,返回实例
public void SetPropertyValue(string propertyName, object propertyValue);   //要保存的对象是object类型
public static SettingsPropertyCollection Properties { get; }  //从配置文件中获取读写对象的方式
定义了以下可读写属性:


public class ProfileCommon : System.Web.Profile.ProfileBase {  //扩展的用户状态类
    
    
public virtual PetShop.BLL.Cart ShoppingCart {   //可读写用户状态对象购物车的属性
        get {
            
return ((PetShop.BLL.Cart)(this.GetPropertyValue("ShoppingCart")));  //访问购物车对象
        }

        
set {
            
this.SetPropertyValue("ShoppingCart", value);  //设置购物车对象
        }

    }

    
    
public virtual PetShop.BLL.Cart WishList {getset;} //
    
    
public virtual PetShop.Model.AddressInfo AccountInfo get ;set;} //略,用户地址信息
    
    
public virtual ProfileCommon GetProfile(string username) {
        
return ((ProfileCommon)(ProfileBase.Create(username)));
    }

}

 

ASP.NET2中创建WebForm同时,自动为每个ASPX页面类声明一个类型为ProfileCommon的成员变量Profile。
当需要保存一个用户的购物车信息时,如果用Session,传统的方式是:
                         
Session["AddressInfo"] = user.Cart;
在ASP.NET2中可以这样写:
                          Profile.AddressInfo = user.Cart;
当设置Profile时,会调用ProfileBase.SetPropertyValue(string propertyName, object propertyValue);
如果应用要将地址信息保存在数据库中,显然没有足够的信息,如变量propertyValue的类型,如何持久化等信息。于是调用ProfileBase.Properties从配置文件中获取写入操作所需要的信息,生成SettingsProperty实例。
创建读写引擎SettingsProperty.SettingsProvider,调用实现的接口函数SettingsProvider.SetProPertyValues(SettingsContext Context,SettingsPropertyValueCollection PropertyValues),完成对象写入工作。
为了能用更直观有效的方式存取购物车对象,ASP.NET2做了很多工作。

ProfileProvider   维护用户状态信息的引擎类,继承自SettingsProvider,继承自ProviderBase。
1.ProviderBase类声明了读取和写入状态信息的两个接口函数。
写入状态信息会引发SetProPertyValues()接口函数的调用,参数是一个SettingsPropertyValueCollection对象,关联一个用户在一个站点活动时的一组状态。每个元素是SettingsPropertyValue对象,SettingsPropertyValue.PropertyValue是真正需要关心的业务逻辑对象,对该对象的存取策略由SettingsPropertyValue.Property定义,属于SettingsProperty类的一个实例,可以在配置文件中配置。根据配置的策略,对象值可以在内存或临时文件中维护,或持久化到数据库中。
这部分可自定义对象存取策略的能力在基类SettingsProvider中声明,这个驱动类根据配置文件中的策略配置实例化一个策略SettingsProperty,来定制状态值
SettingsPropertyValu.Property的存取方式。
根据配置文件中的配置信息(Setting的含义)可以生成一个SettingsProperty对象,需要设置值时,调用SettingsProperty.Provider对象的SetProPertyValues()方法。SettingsProperty.Provider是SettingsProvider类的实例,根据配置文件中的配置,运用策略模式,由引擎管理的工厂类动态创建。

<providers>
 <add name="ShoppingCartProvider" connectionStringName="SQLProfileConnString" type="PetShop.Profile.PetShopProfileProvider"  
applicationName=".NET Pet Shop 4.0"/>
</providers>
<properties>
 <add name="ShoppingCart" type="PetShop.BLL.Cart" allowAnonymous="true" provider="ShoppingCartProvider"/>
</properties>

2.ProfileProvider扩展了SettingsProvider的能力。只要实现ProfileProvider类接口,即可自定义增删用户状态信息。也运用策略模式动态初始化实例,配置信息与SettingsProvider实例的创建共享。
ProfileProvider接口部分成员函数由应用程序自动调用,实现该接口可以维护用户站内活动相关的更多状态信息。

接口成员函数:
SettingsProvider.GetPropertyValues()
传入SettingsProperty集合,返回SettingsPropertyValue集合,依据状态对象的存取策略获取状态对象值。
这个函数在系统需要获取用户信息ProfileCommon时引发,SettingsProperty值从配置文件中读取并初始化。
SettingsProvider.SetPropertyValues()
传入SettingsPropertyValue集合。保存内存中的状态对象值,可以根据保存策略决定是否持久化到数据库中。
其实这个函数是保存用户信息ProfileCommon.Save()时被触发,SettingsPropertyValue的值对应ProfileCommon用户状态信息的值。
ProfileProvider.DeleteProfiles()    删除用户状态信息。用户状态信息包括自定义的状态对象。
DeleteInactiveProfiles(ProfileAuthenticationOption authenticationOption, DateTime userInactiveSinceDate)  删除不活动过期用户。先得到用户列表,再执行删除。
FindProfilesByUserName(ProfileAuthenticationOption authenticationOption, string usernameToMatch, int pageIndex, int pageSize, out int totalRecords)   根据用户名查找状态对象
ProfileInfoCollection GetAllProfiles(ProfileAuthenticationOption authenticationOption, int pageIndex, int pageSize, out int totalRecords)
GetNumberOfInactiveProfiles(ProfileAuthenticationOption authenticationOption, DateTime userInactiveSinceDate)
ProfileInfoCollection GetProfileInfo(ProfileAuthenticationOption authenticationOption, string usernameToMatch, object userInactiveSinceDate, int  pageIndex, int pageSize, out int totalRecords)  登录信息等。
public class CustomProfileInfo    简单地记录用户登录状态等信息。

最后还有一个状态信息总管ProfileManager,静态方法ProfileManager.DeleteProfile(username),会引发ProfileProvider.DeleteProfiles(username)

 


 

没有.NET源码,MSDN描述也不够详尽,不是我不求甚解,实在是暂时解不开,将来理解后,再逐步更新此文档。若误人子弟,概不负责。有错误之处,请路过的高人指正。

抱歉!评论已关闭.