到TL有整整一年了,在這一年中公司從無到有,完成了兩個自動化系統整合項目,老闆一直強調模塊化設計這個理念,但是因爲團隊基礎實在是薄弱,不少規範沒辦法執行起來,以至於這兩個項目的源碼慘不忍睹,代碼寫得很亂,能夠重複利用的模塊實在是太少。因此今年我主要的精力投在軟件開發規範化這一塊,以系統可擴展,模塊化,可複用性爲原則。服務器
雖然自已技術仍是個小菜,但只要有思想就應該是簡單的問題,那麼我從一個「用戶登陸模塊」設計開始,把這個模塊抽離出來,讓全部子系統都可以複用這個登陸組件,而且下降模塊與主框架之間耦合。架構
在製造業的系統架構中,通常分爲好幾個工做站,每一個工做站都有一個子系統,每一個子系統都有須要有用戶登陸權限控制,因此這就意味着每一個子系統都要開發這個模塊,若是子系統比較多,這樣開發成本就比較高,重複代碼也不少,我分析了一下,這個用戶登陸模塊有以下特色:app
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; } } }
我主要總結原理,不少細節就很少寫了,因此服務中的驗證我封裝在另外一組件中,此處省略。框架
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; } } } } }
/****************************************************************************** * 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(); } } } }
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(); } } }
<?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
這個標題能夠根據不一樣子系統功能在配置文件中做對應設置,到此基本完成這個登陸組件的設計,這個組件能夠用於全部子系統的登陸界面,屢次重複利用,減小開發成本。模塊化
附:因本人技術有限,也許會有更好的方法作這個模塊化設計,但願高人指點,在不斷學習中進步。學習