Fix cross appdomain exception

This commit is contained in:
BrennanConroy 2016-07-19 13:10:29 -07:00
parent 8bf0612411
commit 496d94b41f
4 changed files with 86 additions and 6 deletions

View File

@ -26,7 +26,7 @@ namespace Microsoft.AspNetCore.Diagnostics.Elm
public ScopeNode Node { get; set; }
#if NET451
private static string FieldKey = typeof(ElmScope).FullName + ".Value";
private static readonly string FieldKey = $"{typeof(ElmScope).FullName}.Value.{AppDomain.CurrentDomain.Id}";
public static ElmScope Current
{
get

View File

@ -9,6 +9,7 @@ using System;
#if NETSTANDARD1_3
using System.Threading;
#else
using System.Runtime.Remoting;
using System.Runtime.Remoting.Messaging;
#endif
@ -19,7 +20,7 @@ namespace Microsoft.AspNetCore.Diagnostics.EntityFrameworkCore
#if NETSTANDARD1_3
private readonly AsyncLocal<DataStoreErrorLog> _log = new AsyncLocal<DataStoreErrorLog>();
#else
private const string ContextName = "__DataStoreErrorLog";
private static readonly string ContextName = "__DataStoreErrorLog" + AppDomain.CurrentDomain.Id;
#endif
public virtual DataStoreErrorLog LastError
@ -29,7 +30,9 @@ namespace Microsoft.AspNetCore.Diagnostics.EntityFrameworkCore
#if NETSTANDARD1_3
return _log.Value;
#else
return (DataStoreErrorLog)CallContext.LogicalGetData(ContextName);
var handle = CallContext.LogicalGetData(ContextName) as ObjectHandle;
return handle?.Unwrap() as DataStoreErrorLog;
#endif
}
}
@ -44,7 +47,7 @@ namespace Microsoft.AspNetCore.Diagnostics.EntityFrameworkCore
#if NETSTANDARD1_3
_log.Value = new DataStoreErrorLog();
#else
CallContext.LogicalSetData(ContextName, new DataStoreErrorLog());
CallContext.LogicalSetData(ContextName, new ObjectHandle(new DataStoreErrorLog()));
#endif
}

View File

@ -0,0 +1,46 @@
using System;
using Microsoft.Extensions.Logging;
using Xunit;
namespace Microsoft.AspNetCore.Diagnostics.EntityFrameworkCore.Tests
{
#if NET451
public class DataStoreErrorLoggerTest
{
private const string _name = "test";
private static DataStoreErrorLogger SetUp(Func<string, LogLevel, bool> filter = null, string name = null)
{
// Arrange
var provider = new DataStoreErrorLoggerProvider();
var logger = (DataStoreErrorLogger)provider.CreateLogger(name ?? _name);
return logger;
}
private static void DomainFunc()
{
var logger = SetUp();
logger.StartLoggingForCurrentCallContext();
logger.LogInformation(0, "Test");
}
[Fact]
public void ScopeWithChangingAppDomains_DoesNotAccessUnloadedAppDomain()
{
// Arrange
var logger = SetUp();
var domain = AppDomain.CreateDomain("newDomain");
// Act
logger.StartLoggingForCurrentCallContext();
domain.DoCallBack(DomainFunc);
AppDomain.Unload(domain);
logger.LogInformation(0, "Testing");
// Assert
Assert.NotNull(logger.LastError);
}
}
#endif
}

View File

@ -16,9 +16,9 @@ namespace Microsoft.AspNetCore.Diagnostics.Tests
{
private const string _name = "test";
private const string _state = "This is a test";
private Func<string, LogLevel, bool> _filter = (_, __) => true;
private static Func<string, LogLevel, bool> _filter = (_, __) => true;
private Tuple<ElmLogger, ElmStore> SetUp(Func<string, LogLevel, bool> filter = null, string name = null)
private static Tuple<ElmLogger, ElmStore> SetUp(Func<string, LogLevel, bool> filter = null, string name = null)
{
// Arrange
var store = new ElmStore();
@ -305,6 +305,37 @@ namespace Microsoft.AspNetCore.Diagnostics.Tests
Assert.Empty(store.GetActivities());
}
#if NET451
private static void DomainFunc()
{
var t = SetUp();
var logger = t.Item1;
using (logger.BeginScope("newDomain scope"))
{
logger.LogInformation("Test");
}
}
[Fact]
public void ScopeWithChangingAppDomains_DoesNotAccessUnloadedAppDomain()
{
// Arrange
var t = SetUp();
var logger = t.Item1;
var store = t.Item2;
var domain = AppDomain.CreateDomain("newDomain");
// Act
domain.DoCallBack(DomainFunc);
AppDomain.Unload(domain);
using (logger.BeginScope("Scope1"))
{
logger.LogInformation("Testing");
}
Assert.Equal(1, store.Count());
}
#endif
private List<LogInfo> NodeLogs(ScopeNode node, List<LogInfo> logs)
{