https://www.cnblogs.com/smh188/p/11533668.html(我是如何一步步編碼完成萬倉網ERP系統的(一)系統架構)html
https://www.cnblogs.com/smh188/p/11534451.html(我是如何一步步編碼完成萬倉網ERP系統的(二)前端框架)前端
https://www.cnblogs.com/smh188/p/11535449.html(我是如何一步步編碼完成萬倉網ERP系統的(三)登陸)mysql
https://www.cnblogs.com/smh188/p/11541033.html(我是如何一步步編碼完成萬倉網ERP系統的(四)登陸的具體實現)web
https://www.cnblogs.com/smh188/p/11542310.html(我是如何一步步編碼完成萬倉網ERP系統的(五)產品庫設計 1.產品類別)sql
https://www.cnblogs.com/smh188/p/11546917.html(我是如何一步步編碼完成萬倉網ERP系統的(六)產品庫設計 2.百度Ueditor編輯器)數據庫
https://www.cnblogs.com/smh188/p/11572668.html(我是如何一步步編碼完成萬倉網ERP系統的(七)產品庫設計 3.品牌圖片跨域上傳)跨域
https://www.cnblogs.com/smh188/p/11576543.html(我是如何一步步編碼完成萬倉網ERP系統的(八)產品庫設計 4.品牌類別)前端框架
https://www.cnblogs.com/smh188/p/11578185.html(我是如何一步步編碼完成萬倉網ERP系統的(九)產品庫設計 5.產品屬性項) 架構
https://www.cnblogs.com/smh188/p/11589264.html(我是如何一步步編碼完成萬倉網ERP系統的(十)產品庫設計 6.屬性項和類別關聯) 框架
https://www.cnblogs.com/smh188/p/11596459.html(我是如何一步步編碼完成萬倉網ERP系統的(十一)產品庫設計 7.發佈商品)
https://www.cnblogs.com/smh188/p/11610960.html(我是如何一步步編碼完成萬倉網ERP系統的(十二)庫存 1.概述)
https://www.cnblogs.com/smh188/p/11669871.html(我是如何一步步編碼完成萬倉網ERP系統的(十三)庫存 2.加權平均價)
https://www.cnblogs.com/smh188/p/11763319.html(我是如何一步步編碼完成萬倉網ERP系統的(十四)庫存 3.庫存日誌)
萬倉網ERP系統不開源,準備作一個系列,講一講主要的技術點,這些技術點會有源代碼。若是想看全部的源代碼,能夠打道回府了,不必再閱讀下去了,浪費您寶貴的時間。
上一篇我們講了用戶登陸的簡單實現,偏重於加密解密方面,這一篇我們就接着上篇的來,在後臺解密獲得login對象時,如何根據login對象的UserName查詢出數據庫中的用戶。
這就要結合第一篇文章系統架構來講。
首先要在ZJ.Domain層,聲明一個Domain用戶對象,固然實際的用戶對象不可能就這4個字段,在這裏我們只作示例使用。
[Serializable] public class EmployeeDomain { //用戶名 public string EmployeeId { get; set; } //用戶編號 public long EmployeeNo { get; set; } //密碼 public string PassWord { get; set; } //姓名 public string EmployeeName { get; set; } }
第二步,在ZJ.Repository層,聲明一個根據用戶名查詢的接口,返回用戶Domain對象。
public interface IEmployeeRepository { /// <summary> /// 獲取一個員工明細 /// </summary> /// <returns></returns> EmployeeDomain GetEmployeeById(string employeeId); }
第三步,在ZJ.Repository.Core和ZJ.Repository.MySqlCore層實現ZJ.Repository層的接口,若是無特殊說明,代碼都是以ZJ.Repository.Core爲主,ZJ.Repository.MySqlCore和ZJ.Repository.Core差很少,就不在貼了。ZJ.Repository.Core沒有用EF等一些實體類框架,本文也不討論EF實體框架和SQL語句的優劣,萬倉網ERP系統的ZJ.Repository.Core層都是SQL語句。
public class EmployeeRepository : SqlServerDao, IEmployeeRepository { /// <summary> /// 獲取一個員工明細 /// </summary> /// <returns></returns> public EmployeeDomain GetEmployeeById(string employeeId) { string sql = @"SELECT * FROM Employee( NOLOCK ) where EmployeeId=@EmployeeId"; IList<SqlParameter> sqlParams = new List<SqlParameter> { new SqlParameter() { ParameterName ="@EmployeeId", SqlDbType=SqlDbType.VarChar, Size=50, Value = employeeId } }; DataTable dt = SqlHelper.ExecuteDataset(DefaultExecuteConnString, CommandType.Text, sql, sqlParams.ToArray()).Tables[0]; if (dt != null && dt.Rows.Count > 0) { //將DataTable的Row轉換爲EmployeeDomain對象 return dt.Rows[0].ToEntity<EmployeeDomain>(); } return new EmployeeDomain(); } }
第四步,在ZJ.Services層,聲明一個根據用戶名查詢的接口,返回用戶Domain對象,同ZJ.Repository層的接口。
public interface IEmployeeService { /// <summary> /// 獲取一個員工明細 /// </summary> /// <returns></returns> EmployeeDomain GetEmployeeById(string employeeId); }
第五步,在ZJ.Services.Impl層,實現ZJ.Services層的接口。在這一層你會看到用得是ZJ.Repository接口,怎麼回事,這樣就能調通ZJ.Repository.Core的實現嗎(稍後你會看到接口層和實現層怎麼關聯起來)?
public class EmployeeService : IEmployeeService { private readonly IEmployeeRepository _employeeRepository; public EmployeeService(IEmployeeRepository employeeRepository) { _employeeRepository = employeeRepository; } /// <summary> /// 獲取一個員工明細 /// </summary> /// <returns></returns> public EmployeeDomain GetEmployeeById(string employeeId) { return _employeeRepository.GetEmployeeById(employeeId); } }
第六步,在ZJ.BLL寫業務邏輯。
public class EmployeeBLL { private static readonly IEmployeeService _employeeService = ServiceLocator.Instance.GetService<IEmployeeService>(); /// <summary> /// 獲取一個員工明細 /// </summary> /// <returns></returns> public EmployeeDomain GetEmployeeById(string employeeId) { //一堆業務邏輯 //各類判斷等能夠在BLL層,這裏我們就簡單點,直接調用ZJ.Services層的接口 return _employeeService.GetEmployeeById(employeeId); } }
上一步我們用到了ZJ.Infrastructure層的一個類ServiceLocator,基於Microsoft.Practices.Unity的控制反轉,具體我們就直接上代碼吧。
/// <summary> /// Represents the Service Locator. /// </summary> public sealed class ServiceLocator : IServiceProvider { #region Private Fields private readonly IUnityContainer _container; #endregion #region Private Static Fields // ReSharper disable InconsistentNaming private static readonly ServiceLocator instance = new ServiceLocator(); // ReSharper restore InconsistentNaming #endregion #region Ctor /// <summary> /// Initializes a new instance of <c>ServiceLocator</c> class. /// </summary> private ServiceLocator() { UnityConfigurationSection section = (UnityConfigurationSection) ConfigurationManager.GetSection("unity"); _container = new UnityContainer(); section.Configure(_container); } #endregion #region Public Static Properties /// <summary> /// Gets the singleton instance of the <c>ServiceLocator</c> class. /// </summary> public static ServiceLocator Instance { get { return instance; } } #endregion #region Private Methods private IEnumerable<ParameterOverride> GetParameterOverrides(object overridedArguments) { List<ParameterOverride> overrides = new List<ParameterOverride>(); Type argumentsType = overridedArguments.GetType(); argumentsType.GetProperties(BindingFlags.Public | BindingFlags.Instance) .ToList() .ForEach(property => { object propertyValue = property.GetValue(overridedArguments, null); string propertyName = property.Name; overrides.Add(new ParameterOverride(propertyName, propertyValue)); }); return overrides; } #endregion #region Public Methods /// <summary> /// Gets the service instance with the given type. /// </summary> /// <typeparam name="T">The type of the service.</typeparam> /// <returns>The service instance.</returns> public T GetService<T>() { return _container.Resolve<T>(); } public IEnumerable<T> ResolveAll<T>() { return _container.ResolveAll<T>(); } /// <summary> /// Gets the service instance with the given type by using the overrided arguments. /// </summary> /// <typeparam name="T">The type of the service.</typeparam> /// <param name="overridedArguments">The overrided arguments.</param> /// <returns>The service instance.</returns> public T GetService<T>(object overridedArguments) { IEnumerable<ParameterOverride> overrides = GetParameterOverrides(overridedArguments); // ReSharper disable CoVariantArrayConversion return _container.Resolve<T>(overrides.ToArray()); // ReSharper restore CoVariantArrayConversion } /// <summary> /// Gets the service instance with the given type by using the overrided arguments. /// </summary> /// <param name="serviceType">The type of the service.</param> /// <param name="overridedArguments">The overrided arguments.</param> /// <returns>The service instance.</returns> public object GetService(Type serviceType, object overridedArguments) { IEnumerable<ParameterOverride> overrides = GetParameterOverrides(overridedArguments); // ReSharper disable CoVariantArrayConversion return _container.Resolve(serviceType, overrides.ToArray()); // ReSharper restore CoVariantArrayConversion } #endregion #region IServiceProvider Members /// <summary> /// Gets the service instance with the given type. /// </summary> /// <param name="serviceType">The type of the service.</param> /// <returns>The service instance.</returns> public object GetService(Type serviceType) { return _container.Resolve(serviceType); } #endregion }
這樣基本代碼就寫完了,留了個尾巴,接口層如何和實現層結合起來,能夠使用Unity的配置文件(也能夠編寫代碼),放在網站的根目錄下。
<?xml version="1.0" encoding="utf-8"?> <unity xmlns="http://schemas.microsoft.com/practices/2010/unity"> <container> <register type="ZJ.Repository.UserInfo.IEmployeeRepository, ZJ.Repository" mapTo="ZJ.Repository.Core.UserInfo.EmployeeRepository, ZJ.Repository.Core" > <lifetime type="singleton"/> </register> <register type="ZJ.Services.UserInfo.IEmployeeService, ZJ.Services" mapTo="ZJ.Services.Impl.UserInfo.EmployeeService, ZJ.Services.Impl" > <lifetime type="singleton"/> </register> </container> </unity>
web.config中配置了系統基於什麼類型的數據庫(sql server或mysql),若是是mysql數據庫要使用基於mysql的unity配置。
<?xml version="1.0" encoding="utf-8"?> <unity xmlns="http://schemas.microsoft.com/practices/2010/unity"> <container> <register type="ZJ.Repository.UserInfo.IEmployeeRepository, ZJ.Repository" mapTo="ZJ.Repository.MySqlCore.UserInfo.EmployeeRepository, ZJ.Repository.MySqlCore" > <lifetime type="singleton"/> </register> <register type="ZJ.Services.UserInfo.IEmployeeService, ZJ.Services" mapTo="ZJ.Services.Impl.UserInfo.EmployeeService, ZJ.Services.Impl" > <lifetime type="singleton"/> </register> </container> </unity>
同時在web.config中要引用unity的配置文件。
<configSections> <section name="unity" type="Microsoft.Practices.Unity.Configuration.UnityConfigurationSection, Microsoft.Practices.Unity.Configuration" /> </configSections> <unity configSource="Unity.config" />
好,終於大功告成了,能夠在Controller中引用ZJ.BLL層中的EmployeeBLL類了。
private readonly EmployeeBLL employeeBLL = new EmployeeBLL(); employeeBLL.GetEmployeeById(userName);
有興趣的朋友能夠本身搭個測試項目,敲敲代碼。
PS:客官有時間光臨個人小站 萬倉網