我正在创建一个控制台应用程序,并且最近开始将自定义服务添加到IHost容器,因此我可以简单地将IHost传递给任意数量的工厂类,并具有配置它们所需的一切。但是,在将Windows事件日志记录添加为服务时,我一直陷于困境,可以利用一些帮助来解决这一问题。
我在Program中的Main静态方法调用CreateHostBuilder并返回一个IHostBuilder,如下所示。
public static IHostBuilder CreateHostBuilder(string[] args)
{
IConfigurationBuilder configurationBuilder = new ConfigurationBuilder();
configurationBuilder.AddJsonFile("appsettings.json");
IConfiguration configuration = configurationBuilder.Build();
var hostBuilder = Host.CreateDefaultBuilder(args)
.ConfigureLogging((hostContext,logging) =>
{
logging.ClearProviders();
logging.SetMinimumLevel(LogLevel.Information);
logging.AddEventLog(eventViewerSettings =>
{
eventViewerSettings.SourceName = "MeCore2";
eventViewerSettings.LogName = "Application";
eventViewerSettings.MachineName = ".";
});
})
.ConfigureServices(services => services.AddDbContext<MeCore2Context>())
// Add custom service for performing DNS queries
.ConfigureServices(services => services.AddTransient<IDnsQueryService>(DnsQueryFactory.Create))
// Add custom service for Managing Runtime Environment Settings
.ConfigureServices(services => services.AddTransient<IEnvironmentSettings>(EnvironmentSettingsFactory.Create))
// Add custom service for Managing String Extractions
.ConfigureServices(services => services.AddTransient<IExtractStringsService>(ExtraxtStringsFactory.Create))
// Add custom service for IP GeoLocation
.ConfigureServices(services => services.AddTransient<IIpGeolocationService>(IpGeolocationFactory.Create));
return hostBuilder;
}
我的工厂类是这样实现的。
public static class DnsQueryFactory
{
public static DnsQueryService Create(IServiceProvider serviceProvider)
{
bool exceptionDisplayOnly = serviceProvider.GetRequiredService<IEnvironmentSettings>().WriteErrorsToEventLogs;
IHost host = serviceProvider.GetRequiredService<IHost>();
return new DnsQueryService(exceptionDisplayOnly,host);
}
}
我的具体服务构造函数就是这样实现的。
public DnsQueryService(bool exceptionDisplayOnly,IHost host)
{
this.exceptionDisplayOnly = exceptionDisplayOnly;
this.logger = host.Services.GetRequiredService<ILogger>();
this.environmentSettings = host.Services.GetRequiredService<IEnvironmentSettings>();
}
以这种方式设置后运行应用程序时,我无法从主机容器中拉出ILogger,但是我可以拉出ILoggerFactory,然后需要采取一些附加步骤,才能使用功能齐全的ILogger。
我希望能够从Host容器中提取ILogger,并对其进行全面配置,并准备将其用于异常处理,警告和基本信息记录。但是我很困惑,因为我似乎无法获得在主机容器中使用ILoggingBuilder或ILoggerFactory的正确语法。
我从创建一个静态类EventLoggingServices的路径开始,该类将接受IServiceProvider来完成配置步骤并返回ILogger,但这也让我感到困惑。我已经很接近了,但是还没到需要的地方,也找不到一个涵盖这种方法的博客,或者说我以错误的方式开始了。提前感谢您的帮助。
我相信我已经用以下代码回答了自己的问题,它正在写入事件日志。我实现了一种工厂方法来封装ILogger,如下所示。
public static class EventLoggingFactory
{
public static ILogger<IEventLogging> Create(IServiceProvider serviceProvider)
{
return new EventLogging().EventLogger;
}
}
public class EventLogging : IEventLogging
{
#region *-- Private Members --*
private ILogger<IEventLogging> _logger = null;
#endregion
public ILogger<IEventLogging> EventLogger { get { return this._logger; } }
public EventLogging()
{
EventLogSettings settings = new EventLogSettings();
settings.LogName = "Application";
settings.SourceName = "MeCore2";
settings.MachineName = ".";
ILoggerFactory loggerFactory = new LoggerFactory();
loggerFactory.AddProvider(new EventLogLoggerProvider(settings));
this._logger = loggerFactory.CreateLogger<IEventLogging>();
}
}
public interface IEventLogging
{
ILogger<IEventLogging> EventLogger { get; }
}
在我的HostBuilder中,以下内容:
.ConfigureServices(服务=> services.AddTransient(EventLoggingFactory.Create))
我还没有考虑过,但我仍在继续思考服务生命周期。使用这种方法,Ilogger是瞬态的,但这是实现它的最佳方法吗?