小菜模塊化框架設計-複用性登陸組件

背景

    到TL有整整一年了,在這一年中公司從無到有,完成了兩個自動化系統整合項目,老闆一直強調模塊化設計這個理念,但是因爲團隊基礎實在是薄弱,不少規範沒辦法執行起來,以至於這兩個項目的源碼慘不忍睹,代碼寫得很亂,能夠重複利用的模塊實在是太少。因此今年我主要的精力投在軟件開發規範化這一塊,以系統可擴展,模塊化,可複用性爲原則。服務器

    雖然自已技術仍是個小菜,但只要有思想就應該是簡單的問題,那麼我從一個「用戶登陸模塊」設計開始,把這個模塊抽離出來,讓全部子系統都可以複用這個登陸組件,而且下降模塊與主框架之間耦合。架構

    在製造業的系統架構中,通常分爲好幾個工做站,每一個工做站都有一個子系統,每一個子系統都有須要有用戶登陸權限控制,因此這就意味着每一個子系統都要開發這個模塊,若是子系統比較多,這樣開發成本就比較高,重複代碼也不少,我分析了一下,這個用戶登陸模塊有以下特色:app

      • 有統一的界面風格
      • 模塊根據用戶權限不一樣加載對應的系統子系統
      • 模塊標題不同

    咱們如何設計達到組件能夠重複利用?

    1. 複用性:讓全部子系統都可以重複利用這個用戶登陸
    2. 易用性:經過配置文件根據不一樣的子系統設置不同的系統標題,子系統主框架調用組件簡單化
    3. 我後臺作一個WCF服務做爲用戶權限邏輯處理,登陸組件直接調這個服務,把用戶登陸邏輯處理層從系統框架主分離出來成一個獨立模塊,子模塊只須要引入這個組 件,作相應的配置,調用用戶驗證接口,當登陸成功時,組件內部會消息通知主框架(訂閱消息)進行啓動加載主界面,從而達到成功登陸的目的。

    設計思想

    image

    設計步驟

    1.設計WCF Service做後臺用戶登陸驗證處理

    using System.ServiceModel;
    using Xiaocai.Security.IDAL;
    
    namespace Xiaocai.Commons
    {
        // NOTE: You can use the "Rename" command on the "Refactor" menu to change the interface name "IUserService" in both code and config file together.
        [ServiceContract]
        public interface ILoginService
        {
            [OperationContract]
            AuthUser CheckUser(string userId, string password);
        }
    }

     

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Runtime.Serialization;
    using System.ServiceModel;
    using System.Text;
    using Xiaocai.Commons;
    using Xiaocai.Security.Core.Admin;
    using Xiaocai.Security.Core.Helpers;
    using Xiaocai.Security.IDAL;
    
    namespace Xiaocai.SystemHelper.Services
    {
        // NOTE: You can use the "Rename" command on the "Refactor" menu to change the class name "UserService" in code, svc and config file together.
        public class LoginService : ILoginService
        {
            private AuthController _controller;
            public LoginService()
            {
                _controller=new AuthController();
            }
            public AuthUser CheckUser(string userId, string password)
            {
                AuthUser authUser=null;
                bool result=_controller.Login(userId, password);
                if (result)
                {
                    authUser = _controller.AuthUser;
                }
                return authUser;
            }
        }
    }

    我主要總結原理,不少細節就很少寫了,因此服務中的驗證我封裝在另外一組件中,此處省略。框架

    2.發佈這個WCF服務到IIS服務器中,測試如一下是否發佈成功,出現以下頁面表示已成功:

    image

     

     

    3.調用服務客戶端

    using System;
    using System.ServiceModel;
    using Xiaocai.Commons;
    using Xiaocai.Security.IDAL;
    
    namespace Xiaocai.SystemHelper.Proxy
    {
        public class LoginHelper
        {
            public static AuthUser OnLogin(string userId,string password)
            {
                AuthUser authUser = null;
                using (ChannelFactory<ILoginService> channelFactory = new ChannelFactory<ILoginService>("userService"))
                {
                    ILoginService proxy = channelFactory.CreateChannel();
                    using (proxy as IDisposable)
                    {
                        authUser = proxy.CheckUser(userId, password);
                        return authUser;
                    }
                }
            }
        }
    }

     

    4.新建一Winform項目做爲登陸組件,命名爲Xiaocai.SecurityControlLibaray,把項目輸出類型改成類庫,以便子系統主框引入調用。

    /******************************************************************************
    * This document is the property of ShangHai TLian Agent Technology Co., Ltd. (TLAgent).
    * No exploitation or transfer of any information contained herein is permitted 
    * in the absence of an agreement with Xiaocai
    * and neither the document nor any such information
    * may be released without the written consent of Xiaocai
    *  
    * All right reserved by Xiaocai  
    *******************************************************************************
    * Owner: Agan
    * Version: 1.0.0.0
    * Component:for login function
    * Function Description:*
    * Revision / History
    *------------------------------------------------------------------------------
    * Flag     Date     Who             Changes Description
    * -------- -------- --------------- -------------------------------------------
    *   1       20130715 Agan           File created
    
    *------------------------------------------------------------------------------
    */
    
    using System;
    using System.Configuration;
    using System.Windows.Forms;
    using Xiaocai.Commons;
    using Xiaocai.Security.IDAL;
    using Xiaocai.SystemHelper.Proxy;
    namespace Xiaocai.SecurityControlLibaray
    {
        public partial class LoginForm : Form
        {
            public LoginForm()
            {
                InitializeComponent();
            }
    
            public virtual string Title { get; set; }
    
            private void LoginForm_Load(object sender, EventArgs e)
            {
                if (string.IsNullOrEmpty(ConfigurationManager.AppSettings["Title"]))
                {
                    prgTitle.Text = string.Format("{0}", Title);
                }
                else
                {
                    prgTitle.Text = string.Format("{0}", ConfigurationManager.AppSettings["Title"]);
                }
             
                txtUserId.Select();
            }
    
            private void OnLogin(object sender, EventArgs e)
            {
                string userId = txtUserId.Text.Trim();
                string password = txtPassWord.Text.Trim();
                if (string.IsNullOrEmpty(userId) || string.IsNullOrEmpty(password))
                {
                    if (string.IsNullOrEmpty(userId))
                    {
                        MessageHelper.ShowError("用戶名不能爲空!");
                        txtUserId.Focus();
                        txtUserId.SelectAll();
                        return;
                    }
                    if (string.IsNullOrEmpty(password))
                    {
                        MessageHelper.ShowError(@"密碼不能爲空!");
                        txtUserId.Focus();
                        txtUserId.SelectAll();
                        return;
                    }
                   
                    txtUserId.Focus();
                    txtUserId.SelectAll();
                    return;
                }
    
                AuthUser authUser = LoginHelper.OnLogin(userId, password);
                if (authUser!=null)
                {
                    this.Hide();
                    EventService.Publish(authUser);//用戶驗證成功,發佈消息,把登陸用戶傳送出去
                    Application.ThreadException += Application_ThreadException;
                }
                else
                {
                    MessageHelper.ShowError("用戶名或密碼不正確,請聯繫管理員!");
                    txtUserId.Focus();
                    txtUserId.SelectAll();
                }
            }
    
            private static void Application_ThreadException(object sender, System.Threading.ThreadExceptionEventArgs ex)
            {
                string message = string.Format("{0}\r\n操做發生錯誤,您須要退出系統麼?", ex.Exception.Message);
                MessageBox.Show(message);
                Application.Exit();
            }
    
            private void OnCancel(object sender, EventArgs e)
            {
                Application.Exit();
            }
    
    
            private void txtPassWord_KeyDown(object sender, KeyEventArgs e)
            {
                if (e.KeyCode == Keys.Enter)
                {
                    OnLogin(sender,e);
                }
            }
    
            private void txtUserId_KeyDown(object sender, KeyEventArgs e)
            {
                if (e.KeyCode == Keys.Enter)
                {
                    txtPassWord.Focus();
                }
            }
        }
    }

     

    6.系統子框架調用

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Windows.Forms;
    using TLAgent.Commons;
    using TLAgent.Security.Core;
    using TLAgent.Security.IDAL;
    using TLAgent.SecurityControlLibaray;
    
    namespace TLAgent.Assembling.SecurityManager
    {
        static class Program
        {
            /// <summary>
            /// The main entry point for the application.
            /// </summary>
            [STAThread]
            static void Main()
            {
                Application.EnableVisualStyles();
                Application.SetCompatibleTextRenderingDefault(false);
                AppCore.Startup();
                //Application.Run(new LoginForm());
                OnLonin();
            }
    
            private static void OnLonin()
            {
                //訂閱消息
                EventAggregatorRepository.EventAggregator
          .GetEvent<ReceiveObjectEvent>()
          .Subscribe(SuccessLogin);
                Application.Run(new LoginForm());
            }
            /// <summary>
            /// 登陸成功加載主窗體
            /// </summary>
            /// <param name="objParam">用戶實體對象</param>
            private static void SuccessLogin(object objParam)
            {
                SecurityControlLibaray.SplashScreen.Splasher.Show(typeof(SplasherForm));
                MainForm form = new MainForm();
                var user = objParam as AuthUser;
                if (user != null)
                {
                    form.AuthUser = user;
                }
                form.StartPosition = FormStartPosition.CenterScreen;
                form.ShowDialog();
            }
        }
    }

     

    7.配置文件中設置,以下:

    <?xml version="1.0"?>
    <configuration>
      <!--WCF服務配置文件-->
      <system.serviceModel>
        <client>
          <endpoint address="http://localhost/SystemServices/LoginService.svc" binding="basicHttpBinding" contract="Xiaocai.Commons.ILoginService" name="userService"/>
        </client>
      </system.serviceModel>
      
      <appSettings>
        <add key="Title" value="用戶權限管理系統"/><!--系統標題設置-->
        <add key="Copyright" value=" 版權全部:小菜成長記"/><!--系統版權設置-->
          <!-- Database with WebService -->
        <add key="IsRemote" value="N"/>
        <add key="GlobalSessionFactory" value="Xiaocai.Security.DAL.Global.SQLServerSessionFactory,Xiaocai.Security.DAL.Global"/>
    
        <!-- Database without WCFService -->
    
        <add key="Database.SqlServerConn" value="Data Source=localhost,1433;Network Library=DBMSSOCN;Initial Catalog=SecurityDB;User ID=root;Password=12345;"/>
      </appSettings>
    </configuration>

    運行子系統,顯示以下:ide

    image

    這個標題能夠根據不一樣子系統功能在配置文件中做對應設置,到此基本完成這個登陸組件的設計,這個組件能夠用於全部子系統的登陸界面,屢次重複利用,減小開發成本。模塊化

    附:因本人技術有限,也許會有更好的方法作這個模塊化設計,但願高人指點,在不斷學習中進步。學習

    相關文章
    相關標籤/搜索