• 我是如何一步步编码完成万仓网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:客官有时间光临我的小站 万仓网 

  • 相关阅读:
    Loadrunner系列学习--Loadrunner架构(1)
    Loadrunner学习---脚本编写(1)
    loadrunner学习系列---脚本编写(2)
    LoadRunner学习---脚本编写(4)(比较重要)
    LoadRunner内部结构(1)
    pat 1142
    pat 1025
    pat 1140
    c/c++ 常用函数/方法
    pat 1136
  • 原文地址:https://www.cnblogs.com/smh188/p/11541033.html
Copyright © 2020-2023  润新知