把旧系统迁移到.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”] 直 ...
随机推荐
- 八皇后问题 递归实现 C语言 超详细 思路 基础
八皇后问题 :假设 將八个皇后放到国际象棋盘上,使其两两之间无法相互攻击.共有几种摆法? 基础知识: 国际象棋里,棋盘为8X8格. 皇后每步可以沿直线.斜线 走任意格. 思路: 1.想把8个皇后放进去 ...
- _itemmod_extract_enchant随机附魔提取
技能 脚本 spell_extract_enchant 提取一条随机FM 随机FM提取 物品脚本:1.spell_extract_enchant 提取一条随机FM2.spell_extract_enc ...
- java添加templates模板,httpServlet模板改写
为了提高开发效率,通常将一些常用模板添加到快捷键,方法: window-prefrerences-java-editor-templates 代码复制进去apply应用即可 package com.l ...
- JVM——Java虚拟机架构
0. 前言 Java虚拟机(Java virtualmachine)实现了Java语言最重要的特征:即平台无关性. 平台无关性原理:编译后的 Java程序(.class文件)由 JVM执行.JVM屏蔽 ...
- django Admin文档生成器
Django的admindocs应用可以从模型.视图.模板标签等地方获得文档内容. 一.概览 要激活admindocs,请按下面的步骤操作: 在INSTALLED_APPS内添加django.cont ...
- (转载)Attempting to add QLayout "" to MainWindow "", which already has a layout
给QWidget或者QDialog设置布局的时候方式很简单.创建好一个布局:mainLayout,然后不停地把各个控件往mainLayout里面放,最后调用setLayout(mainLayout)就 ...
- MySQL根据when-else条件批量更新
#类型 0:默认 1:黑(0302) 2:白(0110) SELECT * FROM t_power_plat WHERE plat_type=1; UPDATE t_power_plat SET p ...
- Pychram - 使用介绍
Pychram - 使用介绍 PyCharm中Directory与Python package的区别 对于Python而言,有一点是要认识明确的,python作为一个相对而言轻量级的,易用的脚本语言( ...
- Python全栈开发-Day12-Mysql数据库和ORM
本节内容 数据库介绍 mysql 数据库安装使用 mysql管理 mysql 数据类型 常用mysql命令 创建数据库 外键 增删改查表 权限 事务 索引 python 操作mysql ORM sql ...
- Python数据分析-Day1-Numpy模块
1.numpy.genfromtxt读取txt文件 import numpyworld_alcohol = numpy.genfromtxt("world_alcohol.txt" ...