我是如何一步步编码完成万仓网ERP系统的(四)登录的具体实现

  https://www.cnblogs.com/smh188/p/11533668.html(我是如何一步步编码完成万仓网ERP系统的(一)系统架构)

  https://www.cnblogs.com/smh188/p/11534451.html(我是如何一步步编码完成万仓网ERP系统的(二)前端框架)

  https://www.cnblogs.com/smh188/p/11535449.html(我是如何一步步编码完成万仓网ERP系统的(三)登录)

  https://www.cnblogs.com/smh188/p/11541033.html(我是如何一步步编码完成万仓网ERP系统的(四)登录的具体实现)

  https://www.cnblogs.com/smh188/p/11542310.html(我是如何一步步编码完成万仓网ERP系统的(五)产品库设计 1.产品类别)

  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:客官有时间光临我的小站 万仓网 

posted @ 2019-10-14 14:36  万仓网  阅读(582)  评论(0编辑  收藏  举报