让阳光指引生命的每一刻,乘着风,跟随我融化空气

美丽的地球,有美丽的cnblog [hjp3]hjptype=song&player=1&son=http://www.taihugolf.com.cn/villa/sound_00ok01.mp3&autoplay=yes&autoreplay=1&bgcolor=FFFFFF&width=200&height=20[/hjp3]

详解ProfileManager内部是如何运行的!



如大家要转载,请保留本人的版权:
/*
*Description:asp.NET自定义服务器控件内部细节系列教程
*Auther:崇崇-天真的好蓝
*MSN:chongchong2008@msn.com
*Blog:chongchong2008
*Dates:2007-05-20
*Copyright:ChongChong2008 YiChang HuBei China
*/



详解ProfileManager内部是如何运行的!

对于asp.NET2.0内置的profile有人支持,确也有不少高人说不过如此,所谓"鸡肋"!
那么下面我从它的设计意图,在代码层次上予以介绍,在完全了解了它的思想后我们也可以模仿这样的解决方案,如有错误之处还请高人指点!

先运行private static void Initialize (bool throwIfNotEnabled)
CODE如下:

private static void Initialize (bool throwIfNotEnabled)
{
     ProfileManager.InitializeEnabled(true);
     if (ProfileManager.s_InitException != null)
     {
          throw ProfileManager.s_InitException;
     }
     if (throwIfNotEnabled && !ProfileManager.s_Enabled)
     {
          throw new ProviderException(SR.GetString("Profile_not_enabled"));
     }
}

 

在Initialize里面通过ProfileManager.InitializeEnabled(true)来实例化具体的Profile
CODE如下:

private static void InitializeEnabled (bool initProviders)
{
     if (!ProfileManager.s_Initialized || !ProfileManager.s_InitializedProviders)
     {
          lock (ProfileManager.s_Lock)
          {
               if (ProfileManager.s_Initialized && ProfileManager.s_InitializedProviders)
               {
                    return;
               }
               try
               {
                    ProfileSection config = RuntimeConfig.GetAppConfig().Profile;
                    if (!ProfileManager.s_InitializedEnabled)
                    {
                         ProfileManager.s_Enabled = config.Enabled && HttpRuntime.HasAspNetHostingPermission(AspNetHostingPermissionLevel.Low);
                         ProfileManager.s_AutomaticSaveEnabled = ProfileManager.s_Enabled && config.AutomaticSaveEnabled;
                         ProfileManager.s_InitializedEnabled = true;
                    }
                    if ((initProviders && ProfileManager.s_Enabled) && !ProfileManager.s_InitializedProviders)
                    {
                         ProfileManager.InitProviders(config);
                         ProfileManager.s_InitializedProviders = true;
                    }
               }
               catch (Exception exception1)
               {
                    ProfileManager.s_InitException = exception1;
               }
               ProfileManager.s_Initialized = true;
          }
     }
}

 

随后通过ProfileManager.InitProviders(config)具体来实例化
(这里的config是ProfileSection config = RuntimeConfig.GetAppConfig().Profile)
CODE如下:

private static void InitProviders (ProfileSection config)
{
     ProfileManager.s_Providers = new ProfileProviderCollection();
     if (config.Providers != null)
     {
          ProvidersHelper.InstantiateProviders(config.Providers, ProfileManager.s_Providers, typeof(ProfileProvider));
     }
     ProfileManager.s_Providers.SetReadOnly();
     if (config.DefaultProvider == null)
     {
          throw new ProviderException(SR.GetString("Profile_default_provider_not_specified"));
     }
     ProfileManager.s_Provider = ProfileManager.s_Providers[config.DefaultProvider];
     if (ProfileManager.s_Provider == null)
     {
          throw new ConfigurationErrorsException(SR.GetString("Profile_default_provider_not_found"), config.ElementInformation.Properties["providers"].Source, config.ElementInformation.Properties["providers"].LineNumber);
     }
}


 
然后又通过ProvidersHelper.InstantiateProviders(config.Providers, ProfileManager.s_Providers, typeof(ProfileProvider))来处理
CODE如下:

[AspNetHostingPermission(SecurityAction.Demand, Level=AspNetHostingPermissionLevel.Low)]
public static void InstantiateProviders (ProviderSettingsCollection configProviders, ProviderCollection providers, Type providerType)
{
     foreach (ProviderSettings providerSettings in configProviders)
     {
          providers.Add(ProvidersHelper.InstantiateProvider(providerSettings, providerType));
     }
}

 


接着用ProvidersHelper.InstantiateProvider(providerSettings, providerType)的重载来来处理
CODE如下:

[AspNetHostingPermission(SecurityAction.Demand, Level=AspNetHostingPermissionLevel.Low)]
public static ProviderBase InstantiateProvider (ProviderSettings providerSettings, Type providerType)
{
     ProviderBase base1 = null;
     try
     {
          string value = (providerSettings.Type == null) ? null : providerSettings.Type.Trim();
          if (string.IsNullOrEmpty(value))
          {
               throw new ArgumentException(SR.GetString("Provider_no_type_name"));
          }
          Type c = ConfigUtil.GetType(value, "type", providerSettings, true, true);
          if (!providerType.IsAssignableFrom(c))
          {
               throw new ArgumentException(SR.GetString("Provider_must_implement_type", new object[]{providerType.ToString()}));
          }
          base1 = (ProviderBase) HttpRuntime.CreatePublicInstance(c);
          NameValueCollection collection1 = providerSettings.Parameters;
          NameValueCollection config = new NameValueCollection(collection1.Count, StringComparer.Ordinal);
          foreach (string text2 in collection1)
          {
               config[text2] = collection1[text2];
          }
          base1.Initialize(providerSettings.Name, config);
     }
     catch (Exception exception1)
     {
          if (exception1 is ConfigurationException)
          {
               throw;
          }
          throw new ConfigurationErrorsException(exception1.Message, providerSettings.ElementInformation.Properties["type"].Source, providerSettings.ElementInformation.Properties["type"].LineNumber);
     }
     return base1;
}

 

然后交给 base1 = (ProviderBase) HttpRuntime.CreatePublicInstance(c)激活对象
CODE如下:

internal static object CreatePublicInstance (Type type)
{
     return Activator.CreateInstance(type); //原来是在这里最终动态激活对象的
}
 

然后运行base1.Initialize(providerSettings.Name, config)
然后返回 base1 也就是 ProviderBase

 

 

最后static ProfileManager将所有需要完成具体操作的static class转交给Provider Attribute
Provider Attribute的实现如下
CODE如下:

public static ProfileProvider Provider
{
     get
     {
          HttpRuntime.CheckAspNetHostingPermission(AspNetHostingPermissionLevel.Low, "Feature_not_supported_at_this_level");
          ProfileManager.Initialize(true);
          return ProfileManager.s_Provider;
     }
}

 


也就是委托给了abstract ProviderBase类来完成工作
public abstract class ProviderBase
{
     // Constructors
     protected ProviderBase ();

     // Methods
     public virtual void Initialize (string name, NameValueCollection config);

     // Properties
     public virtual string Name { get; }
     public virtual string Description { get; }

     // Instance Fields
     private  string _name;
     private  string _Description;
     private  bool _Initialized;
}

 

而在web.config配置文件里定义了profile defaultProvider = SqlProfileProvider,当然这个是可以灵活扩展的,可以写你自己的ProfileProvider类.


 
SqlProfileProvider 继承 abstract ProfileProvider
CODE如下:

[AspNetHostingPermission(SecurityAction.InheritanceDemand, Level=AspNetHostingPermissionLevel.Minimal), AspNetHostingPermission(SecurityAction.LinkDemand, Level=AspNetHostingPermissionLevel.Minimal)]
public abstract class ProfileProvider : SettingsProvider
{
     // Constructors
     protected ProfileProvider ();

     // Methods
     public abstract int DeleteProfiles (ProfileInfoCollection profiles);
     public abstract int DeleteProfiles (string[] usernames);
     public abstract int DeleteInactiveProfiles (ProfileAuthenticationOption authenticationOption, DateTime userInactiveSinceDate);
     public abstract int GetNumberOfInactiveProfiles (ProfileAuthenticationOption authenticationOption, DateTime userInactiveSinceDate);
     public abstract ProfileInfoCollection GetAllProfiles (ProfileAuthenticationOption authenticationOption, int pageIndex, int pageSize, out int totalRecords);
     public abstract ProfileInfoCollection GetAllInactiveProfiles (ProfileAuthenticationOption authenticationOption, DateTime userInactiveSinceDate, int pageIndex, int pageSize, out int totalRecords);
     public abstract ProfileInfoCollection FindProfilesByUserName (ProfileAuthenticationOption authenticationOption, string usernameToMatch, int pageIndex, int pageSize, out int totalRecords);
     public abstract ProfileInfoCollection FindInactiveProfilesByUserName (ProfileAuthenticationOption authenticationOption, string usernameToMatch, DateTime userInactiveSinceDate, int pageIndex, int pageSize, out int totalRecords);
}
 

 

[AspNetHostingPermission(SecurityAction.LinkDemand, Level=AspNetHostingPermissionLevel.Minimal), AspNetHostingPermission(SecurityAction.InheritanceDemand, Level=AspNetHostingPermissionLevel.Minimal)]
public class SqlProfileProvider : ProfileProvider
{
     // Constructors
     public SqlProfileProvider ();

     // Methods
     public override void Initialize (string name, NameValueCollection config);
     private void CheckSchemaVersion (SqlConnection connection);
     public override SettingsPropertyValueCollection GetPropertyValues (SettingsContext sc, SettingsPropertyCollection properties);
     private void GetPropertyValuesFromDatabase (string userName, SettingsPropertyValueCollection svc);
     public override void SetPropertyValues (SettingsContext sc, SettingsPropertyValueCollection properties);
     private SqlParameter CreateInputParam (string paramName, SqlDbType dbType, object objValue);
     public override int DeleteProfiles (ProfileInfoCollection profiles);
     public override int DeleteProfiles (string[] usernames);
     public override int DeleteInactiveProfiles (ProfileAuthenticationOption authenticationOption, DateTime userInactiveSinceDate);
     public override int GetNumberOfInactiveProfiles (ProfileAuthenticationOption authenticationOption, DateTime userInactiveSinceDate);
     public override ProfileInfoCollection GetAllProfiles (ProfileAuthenticationOption authenticationOption, int pageIndex, int pageSize, out int totalRecords);
     public override ProfileInfoCollection GetAllInactiveProfiles (ProfileAuthenticationOption authenticationOption, DateTime userInactiveSinceDate, int pageIndex, int pageSize, out int totalRecords);
     public override ProfileInfoCollection FindProfilesByUserName (ProfileAuthenticationOption authenticationOption, string usernameToMatch, int pageIndex, int pageSize, out int totalRecords);
     public override ProfileInfoCollection FindInactiveProfilesByUserName (ProfileAuthenticationOption authenticationOption, string usernameToMatch, DateTime userInactiveSinceDate, int pageIndex, int pageSize, out int totalRecords);
     private ProfileInfoCollection GetProfilesForQuery (SqlParameter[] args, ProfileAuthenticationOption authenticationOption, int pageIndex, int pageSize, out int totalRecords);

     // Properties
     public override string ApplicationName { get; set; }
     private int CommandTimeout { get; }

     // Instance Fields
     private  string _AppName;
     private  string _sqlConnectionString;
     private  int _SchemaVersionCheck;
     private  int _CommandTimeout;
}

 

也就是说最后的工作还是由SqlProfileProvider来完成的 


[AspNetHostingPermission(SecurityAction.Demand, Level=AspNetHostingPermissionLevel.Low)]
public static ProviderBase InstantiateProvider (ProviderSettings providerSettings, Type providerType)
{
     ProviderBase base1 = null;
     try
     {
          string value = (providerSettings.Type == null) ? null : providerSettings.Type.Trim();
          if (string.IsNullOrEmpty(value))
          {
               throw new ArgumentException(SR.GetString("Provider_no_type_name"));
          }
          Type c = ConfigUtil.GetType(value, "type", providerSettings, true, true);
          if (!providerType.IsAssignableFrom(c))
          {
               throw new ArgumentException(SR.GetString("Provider_must_implement_type", new object[]{providerType.ToString()}));
          }
          base1 = (ProviderBase) HttpRuntime.CreatePublicInstance(c);
          NameValueCollection collection1 = providerSettings.Parameters;
          NameValueCollection config = new NameValueCollection(collection1.Count, StringComparer.Ordinal);
          foreach (string text2 in collection1)
          {
               config[text2] = collection1[text2];
          }
          base1.Initialize(providerSettings.Name, config);
     }
     catch (Exception exception1)
     {
          if (exception1 is ConfigurationException)
          {
               throw;
          }
          throw new ConfigurationErrorsException(exception1.Message, providerSettings.ElementInformation.Properties["type"].Source, providerSettings.ElementInformation.Properties["type"].LineNumber);
     }
     return base1;
}
 


 

posted on 2007-11-13 23:34 天真的好蓝啊 阅读(128) 评论(0)  编辑 收藏


标题  
姓名  
主页
Email (只有博主才能看到) 
验证码 *  看不清,换一张
内容(请不要发表任何与政治相关的内容)  
  登录  使用高级评论  新用户注册  返回页首  恢复上次提交      
 
另存  打印
最新IT新闻:
 


My Links

Blog Stats

News

与我联系

常用链接

留言簿(1)

我管理的小组

我的标签

随笔分类

随笔档案

相册

搜索

最新评论

阅读排行榜

评论排行榜

集从人之所长,创造博客社区神话,实现梦想!