把旧系统迁移到.Net Core 2.0 日记(2) - 依赖注入/日志NLog
Net Core 大量使用依赖注入(Dependency Inject), 打个比方,我们常用的日志组件有Log4Net,NLog等等.
如果我们要随时替换日志组件,那么代码中就不能直接引用某个组件的内容,也不能直接New 某个组件.
而是应该定义一组接口, 然后包装各个组件,实现这个接口. Net Core 自带组件容器, 启动程序时,指定接口对应的实现.
然后在各个Controller 里, 通过构造函数的参数,把要带过去的接口,把容器里的对象自动传过去
在cshtml view页面,要使用@inject方法, 例如在页面使用Session,就要@inject IHttpContextAccessor _httpContextAccessor
@inject CRM.PermissionLogic plogic
@inject IHttpContextAccessor _httpContextAccessor
@{int userid =(int)_httpContextAccessor.HttpContext.Session.GetInt32("UserId");}
如果要在静态类里使用,则要用到ServiceProvider, 在Startup.cs里注入,然后再用 serviceProvider.GetService<XXX>();
public void ConfigureServices(IServiceCollection services)
{
//注入
services.AddSingleton<IPageHeadBuilder, PageHeadBuilder>(); //解析依赖 对于一个服务A来说,它可能并不是独立的,它还在依赖服务B和服务C,而服务B又依赖服务D和服务E。。
//一个合格的容器得再我们需要服务A时,能够正确的解析这个依赖链,并按照正确的顺序实例化并返回服务A。
//ServiceProvider是ASP.NET Core团队提供的默认的依赖注入容器。
LayoutExtension.serviceProvider= services.BuildServiceProvider();
}
public static class LayoutExtension
{
public static IServiceProvider serviceProvider { get; set; } //定义一个IServiceProvider public static IPageHeadBuilder GetService()
{
return serviceProvider.GetService<IPageHeadBuilder>();
} public static void SetActiveMenuItemSystemName(this IHtmlHelper html, string systemName)
{
var head = GetService();
head.SetActiveMenuItemSystemName(systemName);
} public static string GetActiveMenuItemSystemName(this IHtmlHelper html)
{
var head = GetService();
return head.GetActiveMenuItemSystemName();
}
}
各个页面/Controller ,再调用接口的方法. 所谓的面向接口编程.

Net Core 在Microsoft.Extension.Logging定义了ILogger,ILoggerFactory,ILoggerProvider 这几个接口, 日志组件实现这个接口就可以被调用了.
上网查了一下,NLog已经实现了这些接口了,你用Nuget找NLog.Web.AspNetCore 就已经包装好了. 具体文档,请看这篇文章,非常详细.
https://github.com/NLog/NLog.Web/wiki/Getting-started-with-ASP.NET-Core-2
我们来看一下代码, 要调用NLog, 在Program.cs里
public static IWebHost BuildWebHost(string[] args) =>
WebHost.CreateDefaultBuilder(args)
.UseStartup<Startup>()
.ConfigureLogging((hostingContext, logging) =>
{
logging.AddConsole();
logging.AddDebug();
})
.UseNLog()
.Build();
}
调用NLog写Log, 在构造函数里增加参数,类型是接口,不能是实现类
using Microsoft.Extensions.Logging; public class HelloMiddleware
{
private readonly ILogger<HelloMiddleware> _logger;
private readonly RequestDelegate _next; public HelloMiddleware(RequestDelegate next,ILogger<HelloMiddleware> logger)
{
_next = next;
_logger = logger;
} public Task Invoke(HttpContext httpContext)
{
httpContext.Response.WriteAsync("Hello in Class Invoke"+ Environment.NewLine);
_logger.LogInformation("******hello middleware*********");
return _next(httpContext);
}
}
MVC的controller写法也类似
private readonly CRMContext _context;
private readonly IConfiguration _config;
private readonly ILogger<AccountController> _logger; public AccountController(CRMContext context
IConfiguration configuration,ILogger<AccountController> logger)
{
_context = context;
_config = configuration;
_logger = logger;
}
我们也可以把常用的注入(例如数据库 CRMContext context ) 放在基类BaseController, 子类的构造函数继承基类的构造函数
private readonly IConfiguration _config;
private readonly ILogger<AccountController> _logger; public AccountController(
IConfiguration configuration,ILogger<AccountController> logger):base(context)
{ _config = configuration;
_logger = logger;
}
public abstract class BaseController : Controller
{
protected readonly CRMContext _context; public BaseController(CRMContext context)
{
_context = context;
}
}
我们来看看UseNLog()这个方法的代码,看看做了什么
/// <summary>
/// Use NLog for Dependency Injected loggers.
/// </summary>
public static IWebHostBuilder UseNLog(this IWebHostBuilder builder)
{
return UseNLog(builder, null);
} /// <summary>
/// Use NLog for Dependency Injected loggers.
/// </summary>
/// <param name="builder"></param>
/// <param name="options">Options for logging to NLog with Dependency Injected loggers</param>
/// <returns></returns>
public static IWebHostBuilder UseNLog(this IWebHostBuilder builder, NLogAspNetCoreOptions options)
{
if (builder == null) throw new ArgumentNullException(nameof(builder));
options = options ?? NLogAspNetCoreOptions.Default; builder.ConfigureServices(services =>
{
//note: when registering ILoggerFactory, all non NLog stuff and stuff before this will be removed
services.AddSingleton<ILoggerProvider>(serviceProvider =>
{
ServiceLocator.ServiceProvider = serviceProvider;
return new NLogLoggerProvider(options);
}); //note: this one is called before services.AddSingleton<ILoggerFactory>
if (options.RegisterHttpContextAccessor)
{
services.TryAddSingleton<IHttpContextAccessor, HttpContextAccessor>();
} RegisterHiddenAssembliesForCallSite();
});
return builder;
}
而Log4Net 就没有官方的包装,只有一个第三方包装的, 但包装的不好, 日志的配置不是放在Program.cs, 而是放在StartUp.cs. 我打算有时间再重新包装一次.
参考这篇文章
http://www.cnblogs.com/drivenwinder/p/8300881.html
把旧系统迁移到.Net Core 2.0 日记(2) - 依赖注入/日志NLog的更多相关文章
- 把旧系统迁移到.Net Core 2.0 日记 (15) --Session 改用Redis
安装Microsoft.Extensions.Caching.Redis.Core NuGet中搜索Microsoft.Extensions.Caching.Redis.Core并安装,此NuGet包 ...
- 把旧系统迁移到.Net Core 2.0 日记(1) - Startup.cs 解析
因为自己到开发电脑转到Mac Air,之前的Webform/MVC应用在Mac 跑不起来,而且.Net Core 2.0 已经比较稳定了. 1. 为什么会有跨平台的.Net Core 近年来,我们已 ...
- 把旧系统迁移到.Net Core 2.0 日记 (12) --发布遇到的问题
1. 开发时是在Mac+MySql, 尝试发布时是在SQL2005+Win 2008 (第一版) 在Startup.cs里,数据库连接要改,分页时netcore默认是用offset关键字分页, 如果用 ...
- 把旧系统迁移到.Net Core 2.0 日记(4) - 使用EF+Mysql
因为Mac 不能装SqlServer, 所以把数据库迁移到MySql,然后EntityFramework要改成Pomelo.EntityFrameworkCore.MySql 数据库迁移时,nvarc ...
- 把旧系统迁移到.Net Core 2.0 日记(3) - 详解依赖注入 (转)
关于DI 依赖注入, 转载这篇文章, 写得很好的. ----------------------------- DI在.NET Core里面被提到了一个非常重要的位置, 这篇文章主要再给大家普及一下关 ...
- 把旧系统迁移到.Net Core 2.0 日记 (17) --多租户和SoftDelete
在EF Core 2.0版本中出现了全局过滤新特性即HasQueryFilter,它出现的意义在哪里?能够解决什么问题呢? 通过HasQueryFilter方法来创建过滤器能够允许我们对访问特定数据库 ...
- 把旧系统迁移到.Net Core 2.0 日记(10) -- EF core 和之前版本多对多映射区别
EF Core 现在不支持多对多映射,只能做2个一对多映射. 比如Product和Category 我现在定义Product和Category是多对多关系. 那么实体定义如下: public clas ...
- 把旧系统迁移到.Net Core 2.0 日记 (18) --JWT 认证(Json Web Token)
我们最常用的认证系统是Cookie认证,通常用一般需要人工登录的系统,用户访问授权范围的url时,会自动Redirect到Account/Login,登录后把认证结果存在cookie里. 系统只要找到 ...
- 把旧系统迁移到.Net Core 2.0 日记(8) - EASYUI datagrid+ Dapper+ 导出Excel
迁移也没太大变化,有一个, 之前的Request.QueryString 是返回NameValueCollection, 现在则是返回整个字符串. 你要改成Request.Query[“key”] 直 ...
随机推荐
- 删除node_modules文件
删除node_modules文件夹报错:路径太长,无法删除. npm install rimraf -g rimraf node_modules
- Python.错误解决:scrapy 没有crawl 命令
确保2点: 1.把爬虫.py复制到spiders文件夹里 如执行scrapy crawl demo ,spiders里面就要有demo.py文件 2.在项目文件夹内执行命令 在scrapy.cfg所在 ...
- Redis的EXPIRE过期机制介绍
概述在实际开发过程中经常会遇到一些有时效性数据,比如限时优惠活动,缓存或者验证码之类的.过了一段时间就需要删除这些数据.在关系型数据库中一般都要增加一个字段记录数据的到期时间,然后周期性地检查过期数据 ...
- Vs自定nuget push菜单
1.需要准备 nuget.exe 和 nuget-push.cmd 命名行 nuget.ext 下载地址:https://files.cnblogs.com/files/liuxiaoji/nuget ...
- Event(事件)
1.ZC:之前一直没怎么用过 OpenEvent(...),这次试用居然老是报错... 弄了一下,貌似是 OpenEvent(...)的第一个参数设置成0了... FhEvent_Communicat ...
- 主动触发事件 自定义事件 trigger 及其用法
1. 触发自定义事件方式 js.jq 2. jq 触发 2.1 默认支持的事件 $('#h').on('click',function(){ $(this).append('<p>p< ...
- python实现邮件接口——smtplib模块
1. 思路 使用脚本发送邮件的思路其实和客户端发送邮件一样,过程都是: 登录 —> 写邮件 —> 发送 只不过通过脚本发送时我们需要考虑到整个过程的方方面面.以下为思路导图: 2. Pyt ...
- HeadFirst Ruby 第十五章总结 Saving and loading data
前言 在上一章讲述了如何进行基础的操作,比如 处理 GET 请求的 get route, 再比如下载 gem 等等方面的知识.在这一章节,作者告诉我们如何储存.处理数据.整个过程分三步走: 首先,当 ...
- 雷林鹏分享:XML 树结构
XML 树结构 XML 文档形成了一种树结构,它从"根部"开始,然后扩展到"枝叶". 一个 XML 文档实例 XML 文档使用简单的具有自我描述性的语法: To ...
- Python操作MySql --Python3
Python版本:v3.7 模块:pymysql 1.连接数据库 connectDB.py: # coding:utf-8import pymysql host = 'localhost' # 主机u ...