糖醋小排骨的.net日志

博客园 首页 新随笔 联系 订阅 管理
在Cnforum中看见了很多的自定义信息,比如使用什么数据库,都可以自己定义,那这又是怎么作到的呢,我们就通过CreateUser这个操作来看看怎么获得系统的配置信息,以及怎么应用它.
    首先在注册用户页面的后台文件(CommunityServerControls\User\CreateUser.cs)中的CreateUser_Click方法有如下语句
            
CreateUserStatus createUserStatus = Users.Create(user, true);

调用了User对象的Create方法,那我们再来看看Create方法又作了什么呢?
下面是Create方法的完整版
  1public static CreateUserStatus Create(User user, bool sendEmail, bool ignoreDisallowNames) {
  2            
  3            CSEvents.BeforeUser(user, ObjectState.Create);
  4
  5            CSContext csContext = CSContext.Current;
  6            SiteSettings settings = csContext.SiteSettings;
  7
  8            AccountActivation activation = settings.AccountActivation;
  9            CreateUserStatus status;
 10            
 11            string password = user.Password;
 12            // 2005-02-26: 新增注册IP、磁盘限额,格式化昵称
 13            user.Nickname = Globals.HtmlEncode(user.Nickname);
 14            User nicknameUser = Users.GetUserByNickname(user.Nickname);
 15            if (nicknameUser != null && nicknameUser.UserID > 0)
 16                return CreateUserStatus.DuplicateNickname; 
 17
 18            user.Email = Globals.HtmlEncode(user.Email);
 19            user.DatabaseQuota = settings.UserDatabaseQuota;
 20            user.IPCreated = Globals.IPAddress;
 21
 22
 23            // Lucian: deprecated since it is not handled in CreateUser control
 24            // and regEx validation on control's form.
 25            // Make sure the username begins with an alpha character
 26            //if (!Regex.IsMatch(user.Username, "^[A-Za-z].*"))
 27            //    return CreateUserStatus.InvalidFirstCharacter;
 28
 29            // Check if username is disallowed
 30            if ((!ignoreDisallowNames) && ( DisallowedNames.NameIsDisallowed(user.Username) == true ))
 31                return CreateUserStatus.DisallowedUsername;
 32
 33            // Strip the domain name from the username, if one is present
 34            if( user.Username.IndexOf("\\"> 0 && settings.StripDomainName ) 
 35                user.Username = user.Username.Substring( user.Username.LastIndexOf("\\"+ 1 );
 36
 37            // Set the user's default moderation level
 38            user.ModerationLevel = CSContext.Current.SiteSettings.NewUserModerationLevel;
 39
 40            // Create Instance of the CommonDataProvider
 41            CommonDataProvider dp = CommonDataProvider.Instance();
 42
 43            try {
 44                User createdUser = dp.CreateUpdateDeleteUser(user, DataProviderAction.Create, out status);
 45                
 46                
 47                if(createdUser != null && status == CommunityServer.Components.CreateUserStatus.Created)
 48                {
 49                    csContext.User = createdUser;
 50
 51                    CSConfiguration config = csContext.Config;
 52
 53                    if(settings.EnableDefaultRole && config.DefaultRoles.Length > 0)
 54                    {
 55                        foreach(string role in config.DefaultRoles)
 56                        {
 57                            CommunityServer.Components.Roles.AddUserToRole(createdUser.Username, role);
 58                        }

 59                    }

 60
 61                    // 注册时默认时区和默认语言
 62                    createdUser.Profile.Timezone = settings.TimezoneOffset;
 63                    createdUser.Profile.Language = Globals.Language;
 64                    createdUser.Profile.Save();
 65
 66
 67                    CSEvents.AfterUser(createdUser,ObjectState.Create);
 68                }

 69
 70                
 71            }

 72            catch (CSException e) {
 73                return e.CreateUserStatus;
 74            }

 75
 76            // process the emails now
 77            //
 78            if(sendEmail == true
 79            {
 80
 81                User currentUser = CSContext.Current.User;
 82                if (currentUser.IsForumAdministrator || currentUser.IsBlogAdministrator || currentUser.IsGalleryAdministrator) 
 83                {
 84                    activation = AccountActivation.Automatic;
 85                }

 86                
 87                // TDD HACK 7/19/2004
 88                // we are about to send email to the user notifying them that their account was created, problem is
 89                // when we create the user above we can't set the DateCreated property as this is set through the proc
 90                // but the email needs to know the DateCreated property. So for now, we'll just set the date to the current
 91                // datetime of the server. We don't care about the user local time at this point because the user hasn't
 92                // logged in to set their user profile.
 93                
 94                //user.DateCreated = DateTime.Now;
 95                //user.LastLogin = DateTime.Now;
 96
 97                // based on the account type, we send different emails
 98                //
 99                switch (activation) {
100                    case AccountActivation.AdminApproval:
101                        Emails.UserAccountPending (user);
102                        break;
103                    
104                    case AccountActivation.Email:
105                        Emails.UserCreate(user, password);
106                        break;
107                    
108                    case AccountActivation.Automatic:
109                        Emails.UserCreate(user, password);
110                        break;
111                }

112            }

113            
114            return CreateUserStatus.Created;
115        }

其中的41行使用了CommonDataProvider dp = CommonDataProvider.Instance();
44行是具体的操作User createdUser = dp.CreateUpdateDeleteUser(user, DataProviderAction.Create, out status);
那问题就来了,CommonDataProvider是怎么来的呢,进入CommonDataProvider一看,是一个抽象类,只提供了抽象方法不提供具体实现,而且是用了SingleTon模式来确保只有单一的实例给调用.在CommonDataProvider的构造函数中使用了 CreateDefaultCommonProvider();方法来实例化具体的类
但是这个方法里面只有简单的3句话
 // Get the names of the providers
            
//
            CSConfiguration config = CSConfiguration.GetConfig();

            
// Read the configuration specific information
            
// for this provider
            
//
            Provider sqlForumsProvider = (Provider) config.Providers[CommonDataProviderName];

            
// Read the connection string for this provider
            
//
            
            _defaultInstance 
= DataProviders.CreateInstance(sqlForumsProvider) as CommonDataProvider;

第一句就是今天的重点了,如何获得论坛的配置的呢
在CommunityServerComponents\Configuration\Configurations.cs中,GetConfig方法通过读取磁盘上的communityServer.config文件转化成XMLDoc,再用此XMLDoc来实例化CSConfiguration对象
具体实例化操作就是一般的读取XMLNode的过程,就不重复了,但是还有一点需要注意的是,使用了Cache对象封装了一个CSCache来缓存这些配置信息,这是平时可能会忽略的问题,频繁的IO操作可是系统性能降低的罪魁祸首哦.
下面就简单了,CSCConfiguration对象实列化以后就根据配置信息来具体实列化前面的CommonDataProvider,在我系统上是实列化了SQLCommonDataProvider.接下来的就是具体的业务操作了

所以通过这些东西我们可以把自己系统的很多配置包括一些接口实例化的配置都写在XML的配置文件中,比如具体使用什么数据库,数据库的信息等都存在配置信息中,在运行时动态决定生成何种类来进行业务操作,而不用再重新编译程序
posted on 2006-04-06 14:13  糖醋小排骨  阅读(240)  评论(0)    收藏  举报