[英]Disposing of ILoggerFactory in ASP.NET Core
In my ASP.NET Core project I have written an extention on ILoggerFactory
that adds a custom ILoggerProvider
. 在我的ASP.NET核心项目中,我在ILoggerFactory
上编写了一个扩展,它添加了一个自定义的ILoggerProvider
。 (Similar to NLog.Extensions.Logging ) (与NLog.Extensions.Logging类似)
I'm adding this in Startup.cs
: 我在Startup.cs
添加了这个:
loggerFactory.AddRabbitLogger(Configuration.GetSection(nameof(WebLoggerOptions)));
The logging is working perfectly, however, it sends messages to RabbitMQ and that means it opens a connection and a channel. 日志记录工作正常,但它会向RabbitMQ发送消息,这意味着它会打开一个连接和一个通道。 These cannot stay open so I close the channel and connection in Dispose
( ILoggerProvider
already inherits from IDisposable
) 这些不能保持打开所以我关闭Dispose
的通道和连接( ILoggerProvider
已经从IDisposable
继承)
My test are successful but the problem is that my test output always shows this error 我的测试成功但问题是我的测试输出总是显示此错误
Error while unloading appdomain. (Exception from HRESULT: 0x80131015)
Another problem is that it takes several seconds after the tests are already finished to show that error so I can't start any new tests. 另一个问题是,测试完成后需要几秒钟来显示错误,因此我无法启动任何新测试。
Is there a way to trigger the dispose of the logger provider in my tests? 有没有办法在我的测试中触发记录器提供程序的处理?
Here is the code of my integration test. 这是我的集成测试的代码。 As you can see, I am doing a dispose in the TearDown
如你所见,我正在TearDown
处理
Integration Test 集成测试
public abstract class TestBase
{
private TestServer _server;
protected HttpClient TestHttpClient { get; private set; }
[SetUp]
protected void BaseSetup()
{
_server = new TestServer(new WebHostBuilder()
.UseStartup<Startup>());
TestHttpClient = _server.CreateClient();
}
[TearDown]
public void TearDown()
{
TestHttpClient.Dispose();
_server.Dispose();
}
}
public class MyTestClass : TestBase
{
[Test]
public async Task SendTest()
{
requestUrl = "api/ControllerName/Mehthod";
var response = await TestHttpClient.PostAsync(requestUrl, pardotFormCommand, GetMediaTypeFormatter());
response.StatusCode.Should().Be(HttpStatusCode.OK);
}
}
I was able to fix this by changing my ILoggerFactory
extensions library. 我能够通过更改我的ILoggerFactory
扩展库来解决这个问题。 I also had issues with console applications using this extensions but only when I used more than one service with an ILogger
implementation. 我也遇到过使用这种扩展的控制台应用程序的问题,但只有在我使用ILogger
实现的多个服务时才会出现问题。
In the provider (derived from ILoggerProvider
) there is a CreateLogger
method. 在提供程序(从ILoggerProvider
派生)中有一个CreateLogger
方法。 I found out that within one provider you can have multiple loggers (eg one for each of your asp.net controllers or for each service in your console app). 我发现在一个提供程序中你可以有多个记录器(例如,每个asp.net控制器一个或者你的控制台应用程序中的每个服务)。 I mistakenly thought each logger had it's own provider and I only disposed one ILogger
(the last one). 我错误地认为每个记录器都有它自己的提供者,我只处理了一个ILogger
(最后一个)。
When I changed my ILoggerProvider
code to this, I no longer had hangs or errors in my unit tests 当我将ILoggerProvider
代码更改为此时,我的单元测试中不再出现挂起或错误
public ILogger CreateLogger(string categoryName)
{
var companyLogger = new CompanyLogger(categoryName, _loggerOptions);
_companyLoggers.Add(companyLogger);
return companyLogger;
}
public void Dispose()
{
foreach (var logger in _companyLoggers)
{
logger.Dispose();
}
}
In short, if you want to write a custom ILoggerFactory
with an ILogger
class that needs to be disposed, you will have to keep the ILogger
objects in a private list in your ILoggerProvider
and dispose them all when the Dispose
is called. 简而言之,如果要编写一个带有需要处理的ILogger
类的自定义ILoggerFactory
,则必须将ILogger
对象保存在ILoggerProvider
的私有列表中,并在调用Dispose
时将它们全部Dispose
。 If your ILogger
does not need to be disposed like NLog you don't have to worry about this. 如果您的ILogger
不需要像NLog那样处理,您不必担心这一点。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.