码迷,mamicode.com
首页 > Windows程序 > 详细

[.net core]搭建asp.net core api+ef core+log4net+ioc+单元测试项目与iis部署

时间:2018-10-30 11:19:53      阅读:981      评论:0      收藏:0      [点我收藏+]

标签:ftp   return   oge   sql   builder   environ   包管理   mic   etc   

该项目的目录结构:

技术分享图片

 

CustomModel:自定义模型,用于与界面交互的数据模型。

Model:数据库映射层,EF数据模型与数据库上下文。

IServiceService:业务逻辑层。

CrmApi:API的实现。

CrmApi.Test:API的单元测试。

 

 

数据库映射层:

首先在NuGet包管理器->程序包管理器控制台中安装Entity Framework Core的依赖项:

Install-Package Microsoft.EntityFrameworkCore
Install-Package Microsoft.EntityFrameworkCore.Relational
Install-Package Microsoft.EntityFrameworkCore.SqlServer
Install-Package Microsoft.EntityFrameworkCore.Tools
Install-Package Microsoft.EntityFrameworkCore.SqlServer.Design

生成 EF 数据模型与数据库上下文:

 

Scaffold-DbContext "Server=.;Database=SaierDb;User ID=sa;Password=123;" Microsoft.EntityFrameworkCore.SqlServer -OutputDir Models

 

技术分享图片

如果DbContext中包含数据库中所有的表,那么用第一个构造函数即可,如果多张表分布在不同的 DbContext中,就需要使用第二构造函数,这种情况下需要传递多个DbContext应用到一个连接。

EF Core数据库连接地址:

技术分享图片

 

 

业务逻辑层:

使用DI设计思想,首先创建一个ServiceBase类,所有的接口实现类必须继承这个类,准备需要注入的依赖参数:

技术分享图片

 

接口类:

技术分享图片

 

接口实现类:

技术分享图片

 

 

API层:

这里选择Unity类库作为IOC容器,在NuGet中安装Unity包,新建IocHelper类:

技术分享图片

 

/// <summary>
/// IOC帮助类
/// <para>创建 -2018.10.20 saier-limengqing</para>
/// <para>修改 -</para>
/// </summary>
public class IocHelper
{
    /// <summary>
    /// IOC容器
    /// </summary>
    private static readonly UnityContainer _container;
    /// <summary>
    /// 静态构造方法
    /// </summary>
    static IocHelper()
    {
        _container = new UnityContainer();
    }
    /// <summary>
    /// 注册类型到IOC容器
    /// </summary>
    /// <typeparam name="TInterface">接口</typeparam>
    /// <typeparam name="TImplementation">实现</typeparam>
    public static void Register<TInterface, TImplementation>() where TImplementation : TInterface
    {
        _container.RegisterType<TInterface, TImplementation>(new ContainerControlledLifetimeManager());
    }
    /// <summary>
    /// 从IOC容器中获取接口的实现类
    /// </summary>
    /// <typeparam name="T">接口</typeparam>
    /// <returns>实现</returns>
    public static T Get<T>()
    {
        return _container.Resolve<T>();
    }
    /// <summary>
    /// 从IOC容器中获取接口的实现类
    /// </summary>
    /// <typeparam name="T">接口</typeparam>
    /// <returns>实现</returns>
    public static T Get<T>(Dictionary<string, object> parameterList)
    {
        var parList = new ParameterOverrides();
        if (parameterList != null)
        {
            foreach (KeyValuePair<string, object> item in parameterList)
            {
                parList.Add(item.Key, item.Value);
            }
        }
        return _container.Resolve<T>(parList);
    }
}

在Api的Startup构造方法中使用Ioc注册接口:

技术分享图片

 

在Controller获取注册的接口服务:

技术分享图片

 

请求UserControllerGetUserInfo方法输出结果:

技术分享图片

 

 

项目单元测试:

技术分享图片

 

IntiTest方法中注册接口以及初始化Controller。

 

asp.net core api中配置log4net:

NuGet中添加log4net类库。

技术分享图片

 

在项目中添加log4net.config文件。

 

<?xml version="1.0" encoding="utf-8"?>
<configuration>

  <!-- To customize the asp.net core module uncomment and edit the following section. 
  For more info see https://go.microsoft.com/fwlink/?linkid=838655 -->
  <!--
  <system.webServer>
    <handlers>
      <remove name="aspNetCore"/>
      <add name="aspNetCore" path="*" verb="*" modules="AspNetCoreModule" resourceType="Unspecified"/>
    </handlers>
    <aspNetCore processPath="%LAUNCHER_PATH%" arguments="%LAUNCHER_ARGS%" stdoutLogEnabled="false" stdoutLogFile=".\logs\stdout" />
  </system.webServer>
  -->

  <!-- This section contains the log4net configuration settings -->
  <log4net>
    <appender name="ConsoleAppender" type="log4net.Appender.ConsoleAppender">
      <layout type="log4net.Layout.PatternLayout" value="%date [%thread] %-5level %logger - %message%newline" />
    </appender>

    <appender name="FileAppender" type="log4net.Appender.FileAppender">
      <file value="log-file.log" />
      <appendToFile value="true" />
      <layout type="log4net.Layout.PatternLayout">
        <conversionPattern value="%date [%thread] %-5level %logger [%property{NDC}] - %message%newline" />
      </layout>
    </appender>

    <appender name="RollingLogFileAppender" type="log4net.Appender.RollingFileAppender">
      <file value="logfile/" />
      <appendToFile value="true" />
      <rollingStyle value="Composite" />
      <staticLogFileName value="false" />
      <datePattern value="yyyyMMdd‘.log‘" />
      <maxSizeRollBackups value="10" />
      <maximumFileSize value="1MB" />
      <layout type="log4net.Layout.PatternLayout">
        <conversionPattern value="%date [%thread] %-5level %logger [%property{NDC}] - %message%newline" />
      </layout>
    </appender>

    <!-- Setup the root category, add the appenders and set the default level -->
    <root>
      <level value="ALL" />
      <appender-ref ref="ConsoleAppender" />
      <appender-ref ref="FileAppender" />
      <appender-ref ref="RollingLogFileAppender" />
    </root>

  </log4net>
  
</configuration>

 

Startup构造方法中初始化log4net

 

public Startup(IHostingEnvironment env)
{
    var builder = new ConfigurationBuilder()
        .SetBasePath(env.ContentRootPath)
        .AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
        .AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true)
        .AddEnvironmentVariables();
    Configuration = builder.Build();
    Repository = LogManager.CreateRepository("NETCoreRepository");
    XmlConfigurator.Configure(Repository, new FileInfo("log4net.config"));
}
public static ILoggerRepository Repository { get; private set; }

 

然后控制器中获取对象使用。

 

private readonly ILog _log = LogManager.GetLogger(Startup.Repository.Name, typeof(UserController));
//_log.Info("test");
//_log.Error(ex.Message, ex);

 

测试输出结果:

技术分享图片

 

 

我们正常运行api进行测试是没有问题的,但在做单元测试时会发生报错,原因是我们在单元测试的初始方法中newController,这时候会执行LogManager.GetLogger方法,而由于直接newController所以并没有经过Startup的构造方法没有对log4net进行初始化,才导致报错。所以我们也要将Ilog的接口装载到ioc容器中,然后给容器自动创建接口:

IocHelper类中加入方法:

 

/// <summary>
/// 注册类型到IOC容器
/// </summary>
/// <typeparam name="TInterface">接口</typeparam>
/// <typeparam name="TImplementation">实现</typeparam>
public static void Register<TInterface, TImplementation>(string name, Func<IUnityContainer, object> factoryFunc)
{
    _container.RegisterType<TInterface>(name, new InjectionFactory(factoryFunc));
}
/// <summary>
/// 从IOC容器中获取接口的实现类
/// </summary>
/// <typeparam name="T">接口</typeparam>
/// <returns>实现</returns>
public static T Get<T>(string name)
{
    return _container.Resolve<T>(name);
}

 

Startup类的构造方法中将log4net注册到ioc容器中:

技术分享图片

 

Controller中根据name获取ILog服务:

技术分享图片

在单元测试初始方法中始化log4net

技术分享图片

同样在单元测试的项目中也要添加log4net.config配置文件。

这样调试测试单元测试时可以正常运行,日志也正常输出。

 

 

IIS 中部署 .NET Core API 站点:

确认IIS主页->模块中存在AspNetCoreModule模块,AspNetCoreModule是允许ASP.NET核心应用程序在反向代理配置中在IIS后面运行。

技术分享图片

 

.NET Core应用程序与经典.NET应用程序完全不同,它并不是运行在IIS的工作进程中,而是独立运行的。它独立运行在控制台应用程序中,并通过.NET运行时命令调用。它并没有被加载到IIS工作进程中,但是IIS却加载了名为AspNetCoreModule的本地模块。下图说明了 IISAspNetCoreModule 模块与应用程序之间的关系:

 

 

技术分享图片

 

官方AspNetCoreModule说明:https://docs.microsoft.com/en-us/aspnet/core/fundamentals/servers/aspnet-core-module?view=aspnetcore-2.1

 

 

VS中发布.NET Core应用程序,选择IISFTP等:

技术分享图片

 

然后选择文件系统。

技术分享图片

 

设置目标框架等。

技术分享图片

 

然后在 IIS 中添加一个应用程序池,.NET CLR 版本选择无托管代码。

技术分享图片

 

剩下的与经典ASP.NET应用程序部署的步骤一致,选择新添加的应用程序池即可。

官方ASP.NET CoreIIS托管部署说明:https://docs.microsoft.com/zh-cn/aspnet/core/host-and-deploy/iis/index?view=aspnetcore-2.1

[.net core]搭建asp.net core api+ef core+log4net+ioc+单元测试项目与iis部署

标签:ftp   return   oge   sql   builder   environ   包管理   mic   etc   

原文地址:https://www.cnblogs.com/huayueniansi/p/9872377.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!