詳解ProfileManager內部是如何啟動並執行!

來源:互聯網
上載者:User

如大家要轉載,請保留本人的著作權:
/*
*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;
}
 

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.