把旧系统迁移到.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

 

转载于:https://www.cnblogs.com/zitjubiz/p/net_core_daily_2.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
.Net Core2.1+NLog+数据库连接 <?xml version="1.0" encoding="utf-8" ?> <nlog xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" autoReload="true" throwExceptions="true" internalLogLevel="warn" internalLogFile="logfiles/internal-nlog.txt"> <targets> <target xsi:type="Null" name="blackhole" /> <target name="database" xsi:type="Database" dbProvider="System.Data.SqlClient" connectionString="Data Source=127.0.0.1;Initial Catalog=MiddleData;User ID=lzhu;Password=bl123456;" > <!-- create table NLog ( Id int identity, Application nvarchar(50) null, Logged datetime null, Level nvarchar(50) null, Message nvarchar(512) null, Logger nvarchar(250) null, Callsite nvarchar(512) null, Exception nvarchar(512) null, constraint PK_NLOG primary key (Id) ) --> <commandText> insert into nlog ( Application, Logged, Level, Message, Logger, CallSite, Exception ) values ( @Application, @Logged, @Level, @Message, @Logger, @Callsite, @Exception ); </commandText> <parameter name="@application" layout="NLogTestDemo" /> <parameter name="@logged" layout="${date}" /> <parameter name="@level" layout="${level}" /> <parameter name="@message" layout="${message}" /> <parameter name="@logger" layout="${logger}" /> <parameter name="@callSite" layout="${callsite:filename=true}" /> <parameter name="@exception" layout="${exception:tostring}" /> </target> </targets> <rules> <!--Skip Microsoft logs and so log only own logs--> <logger name="Microsoft.*" minlevel="Trace" writeTo="blackhole" final="true" /> <logger name="NLogTestDemo.*" minlevel="Info" writeTo="database" /> </rules> </nlog>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值