私はどのように1歩1歩コードして万倉網ERPシステムの(4)登録の具体的な実現を完成します

29068 ワード

https://www.cnblogs.com/smh188/p/11533668.html(私はどのようにして万倉網ERPシステムを一歩一歩コードして完成したのか(一)システムアーキテクチャ)
  https://www.cnblogs.com/smh188/p/11534451.html(私はどのように1歩1歩コードして万倉網ERPシステムの(2)フロントエンドフレームワークを完成します)
  https://www.cnblogs.com/smh188/p/11535449.html(私はどのように1歩1歩コードして万倉網ERPシステムの(3)登録を完成します)
  https://www.cnblogs.com/smh188/p/11541033.html(私はどのように1歩1歩コードして万倉網ERPシステムの(4)登録の具体的な実現を完成します)
  https://www.cnblogs.com/smh188/p/11542310.html(私はどのように1歩1歩コードして万倉網ERPシステムの(5)製品ライブラリの設計を完成します.製品カテゴリ)
万倉網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; }
    }

ステップ2はZJ.Repositoryレイヤは、ユーザー名に基づいてクエリーされたインタフェースを宣言し、ユーザーDomainオブジェクトを返します.
    public interface IEmployeeRepository
    {
        /// 
        ///  
        /// 
        /// 
        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
    {
        /// 
        ///  
        /// 
        /// 
        public EmployeeDomain GetEmployeeById(string employeeId)
        {
            string sql = @"SELECT * FROM Employee( NOLOCK ) where EmployeeId=@EmployeeId";
            IList sqlParams = new List
            {
                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();
            }
            return new EmployeeDomain();
        }
    }

  第四步,在ZJ.Services层,声明一个根据用户名查询的接口,返回用户Domain对象,同ZJ.Repository层的接口。

    public interface IEmployeeService
    {
        /// 
        ///  
        /// 
        /// 
        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;
        }

        /// 
        ///  
        /// 
        /// 
        public EmployeeDomain GetEmployeeById(string employeeId)
        {
            return _employeeRepository.GetEmployeeById(employeeId);
        }
    }

  第六步,在ZJ.BLL写业务逻辑。

    public class EmployeeBLL
    {
        private static readonly IEmployeeService _employeeService = ServiceLocator.Instance.GetService();

        /// 
        ///  
        /// 
        /// 
        public EmployeeDomain GetEmployeeById(string employeeId)
        {
            // 
            // BLL , , ZJ.Services 
            return _employeeService.GetEmployeeById(employeeId);
        }
    }

  上一步咱们用到了ZJ.Infrastructure层的一个类ServiceLocator,基于Microsoft.Practices.Unity的控制反转,具体咱们就直接上代码吧。

  /// 
  ///   Represents the Service Locator.
  /// 
  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

    /// 
    ///   Initializes a new instance of ServiceLocator class.
    /// 
    private ServiceLocator()
    {
      UnityConfigurationSection section = (UnityConfigurationSection) ConfigurationManager.GetSection("unity");
      _container = new UnityContainer();
      section.Configure(_container);
    }

    #endregion

    #region Public Static Properties

    /// 
    ///   Gets the singleton instance of the ServiceLocator class.
    /// 
    public static ServiceLocator Instance
    {
      get { return instance; }
    }

    #endregion

    #region Private Methods

    private IEnumerable GetParameterOverrides(object overridedArguments)
    {
      List overrides = new List();
      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

    /// 
    ///   Gets the service instance with the given type.
    /// 
    /// The type of the service.
    /// The service instance.
    public T GetService()
    {
      return _container.Resolve();
    }

    public IEnumerable ResolveAll()
    {
      return _container.ResolveAll();
    }

    /// 
    ///   Gets the service instance with the given type by using the overrided arguments.
    /// 
    /// The type of the service.
    /// The overrided arguments.
    /// The service instance.
    public T GetService(object overridedArguments)
    {
      IEnumerable overrides = GetParameterOverrides(overridedArguments);
      // ReSharper disable CoVariantArrayConversion
      return _container.Resolve(overrides.ToArray());
      // ReSharper restore CoVariantArrayConversion
    }

    /// 
    ///   Gets the service instance with the given type by using the overrided arguments.
    /// 
    /// The type of the service.
    /// The overrided arguments.
    /// The service instance.
    public object GetService(Type serviceType, object overridedArguments)
    {
      IEnumerable overrides = GetParameterOverrides(overridedArguments);
      // ReSharper disable CoVariantArrayConversion
      return _container.Resolve(serviceType, overrides.ToArray());
      // ReSharper restore CoVariantArrayConversion
    }

    #endregion

    #region IServiceProvider Members

    /// 
    ///   Gets the service instance with the given type.
    /// 
    /// The type of the service.
    /// The service instance.
    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では、mysqlデータベースでmysqlベースのunity構成を使用する場合、システムがどのタイプのデータベース(sql serverまたはmysql)に基づいて構成されています.
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:お客様が時間があれば、私の小さな駅万倉網にお越しください