Skip to content

Instantly share code, notes, and snippets.

@twcclegg
Created August 18, 2015 17:52
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save twcclegg/2a931390eaf95d9367c9 to your computer and use it in GitHub Desktop.
Save twcclegg/2a931390eaf95d9367c9 to your computer and use it in GitHub Desktop.
diff --git a/src/Appender/AdoNetAppender.cs b/src/Appender/AdoNetAppender.cs
index c9600f2..2f4f27e 100644
--- a/src/Appender/AdoNetAppender.cs
+++ b/src/Appender/AdoNetAppender.cs
@@ -17,9 +17,6 @@
//
#endregion
-// SSCLI 1.0 has no support for ADO.NET
-#if !SSCLI
-
using System;
using System.Collections;
using System.Configuration;
@@ -1253,5 +1250,3 @@ virtual public void FormatValue(IDbCommand command, LoggingEvent loggingEvent)
#endregion // Private Instance Fields
}
}
-
-#endif // !SSCLI
\ No newline at end of file
diff --git a/src/Appender/AnsiColorTerminalAppender.cs b/src/Appender/AnsiColorTerminalAppender.cs
index 3ad375f..58013d8 100644
--- a/src/Appender/AnsiColorTerminalAppender.cs
+++ b/src/Appender/AnsiColorTerminalAppender.cs
@@ -339,10 +339,6 @@ override protected void Append(log4net.Core.LoggingEvent loggingEvent)
}
}
-#if NETCF_1_0
- // Write to the output stream
- Console.Write(loggingMessage);
-#else
if (m_writeToErrorStream)
{
// Write to the error stream
@@ -353,7 +349,6 @@ override protected void Append(log4net.Core.LoggingEvent loggingEvent)
// Write to the output stream
Console.Write(loggingMessage);
}
-#endif
}
diff --git a/src/Appender/AppenderSkeleton.cs b/src/Appender/AppenderSkeleton.cs
index bc11683..c04a761 100644
--- a/src/Appender/AppenderSkeleton.cs
+++ b/src/Appender/AppenderSkeleton.cs
@@ -321,7 +321,7 @@ public void DoAppend(LoggingEvent loggingEvent)
{
ErrorHandler.Error("Failed in DoAppend", ex);
}
-#if !MONO && !NET_2_0
+#if NETCF
// on .NET 2.0 (and higher) and Mono (all profiles),
// exceptions that do not derive from System.Exception will be
// wrapped in a RuntimeWrappedException by the runtime, and as
@@ -428,7 +428,7 @@ public void DoAppend(LoggingEvent[] loggingEvents)
{
ErrorHandler.Error("Failed in Bulk DoAppend", ex);
}
-#if !MONO && !NET_2_0
+#if NETCF
// on .NET 2.0 (and higher) and Mono (all profiles),
// exceptions that do not derive from System.Exception will be
// wrapped in a RuntimeWrappedException by the runtime, and as
diff --git a/src/Appender/AspNetTraceAppender.cs b/src/Appender/AspNetTraceAppender.cs
index 82f9569..08a49a7 100644
--- a/src/Appender/AspNetTraceAppender.cs
+++ b/src/Appender/AspNetTraceAppender.cs
@@ -17,9 +17,7 @@
//
#endregion
-// .NET Compact Framework 1.0 has no support for ASP.NET
-// SSCLI 1.0 has no support for ASP.NET
-#if !NETCF && !SSCLI && !CLIENT_PROFILE
+#if !NETCF && !CLIENT_PROFILE
using System.Web;
@@ -152,4 +150,4 @@ public PatternLayout Category
}
}
-#endif // !NETCF && !SSCLI
+#endif // !NETCF
diff --git a/src/Appender/ColoredConsoleAppender.cs b/src/Appender/ColoredConsoleAppender.cs
index 0fe2d70..332d1c7 100644
--- a/src/Appender/ColoredConsoleAppender.cs
+++ b/src/Appender/ColoredConsoleAppender.cs
@@ -17,16 +17,8 @@
//
#endregion
-// MONO 1.0 Beta mcs does not like #if !A && !B && !C syntax
-
-// .NET Compact Framework 1.0 has no support for Win32 Console API's
+// .NET Compact Framework has no support for Win32 Console API's
#if !NETCF
-// .Mono 1.0 has no support for Win32 Console API's
-#if !MONO
-// SSCLI 1.0 has no support for Win32 Console API's
-#if !SSCLI
-// We don't want framework or platform specific code in the CLI version of log4net
-#if !CLI_1_0
using System;
using System.Globalization;
@@ -660,7 +652,4 @@ internal ushort CombinedColor
}
}
-#endif // !CLI_1_0
-#endif // !SSCLI
-#endif // !MONO
#endif // !NETCF
diff --git a/src/Appender/ConsoleAppender.cs b/src/Appender/ConsoleAppender.cs
index 84ad172..5baf676 100644
--- a/src/Appender/ConsoleAppender.cs
+++ b/src/Appender/ConsoleAppender.cs
@@ -150,10 +150,6 @@ virtual public string Target
/// </remarks>
override protected void Append(LoggingEvent loggingEvent)
{
-#if NETCF_1_0
- // Write to the output stream
- Console.Write(RenderLoggingEvent(loggingEvent));
-#else
if (m_writeToErrorStream)
{
// Write to the error stream
@@ -164,7 +160,6 @@ override protected void Append(LoggingEvent loggingEvent)
// Write to the output stream
Console.Write(RenderLoggingEvent(loggingEvent));
}
-#endif
}
/// <summary>
diff --git a/src/Appender/EventLogAppender.cs b/src/Appender/EventLogAppender.cs
index 9cc031e..4ac3811 100644
--- a/src/Appender/EventLogAppender.cs
+++ b/src/Appender/EventLogAppender.cs
@@ -17,12 +17,7 @@
//
#endregion
-// MONO 1.0 Beta mcs does not like #if !A && !B && !C syntax
-
-// .NET Compact Framework 1.0 has no support for EventLog
#if !NETCF
-// SSCLI 1.0 has no support for EventLog
-#if !SSCLI
using System;
using System.Diagnostics;
@@ -686,5 +681,4 @@ private static int GetMaxEventLogMessageSize()
}
}
-#endif // !SSCLI
#endif // !NETCF
diff --git a/src/Appender/LocalSyslogAppender.cs b/src/Appender/LocalSyslogAppender.cs
index 2a4ceb9..4ca4c21 100644
--- a/src/Appender/LocalSyslogAppender.cs
+++ b/src/Appender/LocalSyslogAppender.cs
@@ -17,9 +17,8 @@
//
#endregion
-// .NET Compact Framework 1.0 has no support for Marshal.StringToHGlobalAnsi
-// SSCLI 1.0 has no support for Marshal.StringToHGlobalAnsi
-#if !NETCF && !SSCLI
+// .NET Compact Framework has no support for Marshal.StringToHGlobalAnsi
+#if !NETCF
using System;
using System.Runtime.InteropServices;
diff --git a/src/Appender/ManagedColoredConsoleAppender.cs b/src/Appender/ManagedColoredConsoleAppender.cs
index a1a06ac..60b64b6 100644
--- a/src/Appender/ManagedColoredConsoleAppender.cs
+++ b/src/Appender/ManagedColoredConsoleAppender.cs
@@ -21,11 +21,6 @@
// http://msdn.microsoft.com/en-us/library/system.console.foregroundcolor.aspx
// Disable for unsupported targets
#if !NETCF
-#if !SSCLI
-#if !CLI_1_0
-#if !MONO_1_0
-#if !NET_1_0
-#if !NET_1_1
// The original ColoredConsoleAppender was written before the .NET framework
// (and Mono) had built-in support for console colors so it was written using
@@ -340,9 +335,4 @@ public ConsoleColor BackColor
}
}
-#endif
-#endif
-#endif // !MONO_1_0
-#endif // !CLI_1_0
-#endif // !SSCLI
#endif // !NETCF
diff --git a/src/Appender/NetSendAppender.cs b/src/Appender/NetSendAppender.cs
index d221a6e..b4e0d8d 100644
--- a/src/Appender/NetSendAppender.cs
+++ b/src/Appender/NetSendAppender.cs
@@ -17,16 +17,8 @@
//
#endregion
-// MONO 1.0 Beta mcs does not like #if !A && !B && !C syntax
-
-// .NET Compact Framework 1.0 has no support for Win32 NetMessageBufferSend API
+// .NET Compact Framework has no support for Win32 NetMessageBufferSend API
#if !NETCF
-// MONO 1.0 has no support for Win32 NetMessageBufferSend API
-#if !MONO
-// SSCLI 1.0 has no support for Win32 NetMessageBufferSend API
-#if !SSCLI
-// We don't want framework or platform specific code in the CLI version of log4net
-#if !CLI_1_0
using System;
using System.Globalization;
@@ -419,7 +411,4 @@ override protected bool RequiresLayout
}
}
-#endif // !CLI_1_0
-#endif // !SSCLI
-#endif // !MONO
#endif // !NETCF
\ No newline at end of file
diff --git a/src/Appender/OutputDebugStringAppender.cs b/src/Appender/OutputDebugStringAppender.cs
index 326e5d3..64fb387 100644
--- a/src/Appender/OutputDebugStringAppender.cs
+++ b/src/Appender/OutputDebugStringAppender.cs
@@ -17,13 +17,6 @@
//
#endregion
-// MONO 1.0 has no support for Win32 OutputDebugString API
-#if !MONO
-// SSCLI 1.0 has no support for Win32 OutputDebugString API
-#if !SSCLI
-// We don't want framework or platform specific code in the CLI version of log4net
-#if !CLI_1_0
-
using System.Runtime.InteropServices;
using log4net.Layout;
@@ -122,7 +115,3 @@ override protected bool RequiresLayout
#endregion // Protected Static Methods
}
}
-
-#endif // !CLI_1_0
-#endif // !SSCLI
-#endif // !MONO
diff --git a/src/Appender/RollingFileAppender.cs b/src/Appender/RollingFileAppender.cs
index c1b7705..3044fc1 100644
--- a/src/Appender/RollingFileAppender.cs
+++ b/src/Appender/RollingFileAppender.cs
@@ -239,7 +239,7 @@ public RollingFileAppender()
#region Public Instance Properties
-#if !NET_1_0 && !CLI_1_0 && !NETCF
+#if !NETCF
/// <summary>
/// Gets or sets the strategy for determining the current date and time. The default
/// implementation is to use LocalDateTime which internally calls through to DateTime.Now.
@@ -796,7 +796,7 @@ private void RollOverIfDateBoundaryCrossing()
{
DateTime last;
using(SecurityContext.Impersonate(this)) {
-#if !NET_1_0 && !CLI_1_0 && !NETCF
+#if !NETCF
if (DateTimeStrategy is UniversalDateTime)
{
last = System.IO.File.GetLastWriteTimeUtc(m_baseFileName);
@@ -805,7 +805,7 @@ private void RollOverIfDateBoundaryCrossing()
{
#endif
last = System.IO.File.GetLastWriteTime(m_baseFileName);
-#if !NET_1_0 && !CLI_1_0 && !NETCF
+#if !NETCF
}
#endif
}
@@ -1699,7 +1699,7 @@ public DateTime Now
}
}
-#if !NET_1_0 && !CLI_1_0 && !NETCF
+#if !NETCF
/// <summary>
/// Implementation of <see cref="IDateTime"/> that returns the current time as the coordinated universal time (UTC).
/// </summary>
diff --git a/src/Appender/SmtpAppender.cs b/src/Appender/SmtpAppender.cs
index e1749a2..d29b7cc 100644
--- a/src/Appender/SmtpAppender.cs
+++ b/src/Appender/SmtpAppender.cs
@@ -17,19 +17,14 @@
//
#endregion
-// .NET Compact Framework 1.0 has no support for System.Web.Mail
-// SSCLI 1.0 has no support for System.Web.Mail
-#if !NETCF && !SSCLI
+// .NET Compact Framework has no support for System.Web.Mail
+#if !NETCF
using System;
using System.IO;
using System.Text;
-#if NET_2_0
using System.Net.Mail;
-#else
-using System.Web.Mail;
-#endif
using log4net.Layout;
using log4net.Core;
@@ -324,7 +319,6 @@ public MailPriority Priority
set { m_mailPriority = value; }
}
-#if NET_2_0
/// <summary>
/// Enable or disable use of SSL when sending e-mail message
/// </summary>
@@ -348,7 +342,6 @@ public string ReplyTo
get { return m_replyTo; }
set { m_replyTo = value; }
}
-#endif
/// <summary>
/// Gets or sets the subject encoding to be used.
@@ -444,7 +437,6 @@ override protected bool RequiresLayout
/// <param name="messageBody">the body text to include in the mail</param>
virtual protected void SendEmail(string messageBody)
{
-#if NET_2_0
// .NET 2.0 has a new API for SMTP email System.Net.Mail
// This API supports credentials and multiple hosts correctly.
// The old API is deprecated.
@@ -502,83 +494,6 @@ virtual protected void SendEmail(string messageBody)
// behaviour compared to .NET 1.x. We would need a SendCompletedCallback to log errors.
smtpClient.Send(mailMessage);
}
-#else
- // .NET 1.x uses the System.Web.Mail API for sending Mail
-
- MailMessage mailMessage = new MailMessage();
- mailMessage.Body = messageBody;
- mailMessage.BodyEncoding = m_bodyEncoding;
- mailMessage.From = m_from;
- mailMessage.To = m_to;
- if (m_cc != null && m_cc.Length > 0)
- {
- mailMessage.Cc = m_cc;
- }
- if (m_bcc != null && m_bcc.Length > 0)
- {
- mailMessage.Bcc = m_bcc;
- }
- mailMessage.Subject = m_subject;
-#if !MONO && !NET_1_0 && !NET_1_1 && !CLI_1_0
- mailMessage.SubjectEncoding = m_subjectEncoding;
-#endif
- mailMessage.Priority = m_mailPriority;
-
-#if NET_1_1
- // The Fields property on the MailMessage allows the CDO properties to be set directly.
- // This property is only available on .NET Framework 1.1 and the implementation must understand
- // the CDO properties. For details of the fields available in CDO see:
- //
- // http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cdosys/html/_cdosys_configuration_coclass.asp
- //
-
- try
- {
- if (m_authentication == SmtpAuthentication.Basic)
- {
- // Perform basic authentication
- mailMessage.Fields.Add("http://schemas.microsoft.com/cdo/configuration/smtpauthenticate", 1);
- mailMessage.Fields.Add("http://schemas.microsoft.com/cdo/configuration/sendusername", m_username);
- mailMessage.Fields.Add("http://schemas.microsoft.com/cdo/configuration/sendpassword", m_password);
- }
- else if (m_authentication == SmtpAuthentication.Ntlm)
- {
- // Perform integrated authentication (NTLM)
- mailMessage.Fields.Add("http://schemas.microsoft.com/cdo/configuration/smtpauthenticate", 2);
- }
-
- // Set the port if not the default value
- if (m_port != 25)
- {
- mailMessage.Fields.Add("http://schemas.microsoft.com/cdo/configuration/smtpserverport", m_port);
- }
- }
- catch(MissingMethodException missingMethodException)
- {
- // If we were compiled against .NET 1.1 but are running against .NET 1.0 then
- // we will get a MissingMethodException when accessing the MailMessage.Fields property.
-
- ErrorHandler.Error("SmtpAppender: Authentication and server Port are only supported when running on the MS .NET 1.1 framework", missingMethodException);
- }
-#else
- if (m_authentication != SmtpAuthentication.None)
- {
- ErrorHandler.Error("SmtpAppender: Authentication is only supported on the MS .NET 1.1 or MS .NET 2.0 builds of log4net");
- }
-
- if (m_port != 25)
- {
- ErrorHandler.Error("SmtpAppender: Server Port is only supported on the MS .NET 1.1 or MS .NET 2.0 builds of log4net");
- }
-#endif // if NET_1_1
-
- if (m_smtpHost != null && m_smtpHost.Length > 0)
- {
- SmtpMail.SmtpServer = m_smtpHost;
- }
-
- SmtpMail.Send(mailMessage);
-#endif // if NET_2_0
}
#endregion // Protected Methods
@@ -604,10 +519,8 @@ virtual protected void SendEmail(string messageBody)
private MailPriority m_mailPriority = MailPriority.Normal;
-#if NET_2_0
private bool m_enableSsl = false;
private string m_replyTo;
-#endif
#endregion // Private Instance Fields
@@ -649,4 +562,4 @@ public enum SmtpAuthentication
}
}
-#endif // !NETCF && !SSCLI
+#endif // !NETCF
diff --git a/src/Appender/UdpAppender.cs b/src/Appender/UdpAppender.cs
index ce5342b..158a9e1 100644
--- a/src/Appender/UdpAppender.cs
+++ b/src/Appender/UdpAppender.cs
@@ -474,7 +474,7 @@ protected virtual void InitializeClientConnection()
{
if (this.LocalPort == 0)
{
-#if NETCF || NET_1_0 || SSCLI_1_0 || CLI_1_0
+#if NETCF
this.Client = new UdpClient();
#else
this.Client = new UdpClient(RemoteAddress.AddressFamily);
@@ -482,7 +482,7 @@ protected virtual void InitializeClientConnection()
}
else
{
-#if NETCF || NET_1_0 || SSCLI_1_0 || CLI_1_0
+#if NETCF
this.Client = new UdpClient(this.LocalPort);
#else
this.Client = new UdpClient(this.LocalPort, RemoteAddress.AddressFamily);
diff --git a/src/AssemblyInfo.cs b/src/AssemblyInfo.cs
index b387a84..6bd74e9 100644
--- a/src/AssemblyInfo.cs
+++ b/src/AssemblyInfo.cs
@@ -20,12 +20,7 @@
using System.Reflection;
using System.Runtime.CompilerServices;
-#if (!SSCLI)
-//
-// log4net makes use of static methods which cannot be made com visible
-//
[assembly: System.Runtime.InteropServices.ComVisible(false)]
-#endif
//
// log4net is CLS compliant
@@ -39,7 +34,7 @@
[assembly: System.Security.AllowPartiallyTrustedCallers]
#endif
-#if (NET_4_0)
+#if (FRAMEWORK_4_0_OR_ABOVE)
//
// Allows partial trust applications (e.g. ASP.NET shared hosting) on .NET 4.0 to work
// given our implementation of ISerializable.
@@ -53,13 +48,9 @@
// associated with an assembly.
//
-#if (CLI_1_0)
-[assembly: AssemblyTitle("Apache log4net for CLI 1.0 Compatible Frameworks")]
-#elif (NET_1_0)
-[assembly: AssemblyTitle("Apache log4net for .NET Framework 1.0")]
-#elif (NET_1_1)
-[assembly: AssemblyTitle("Apache log4net for .NET Framework 1.1")]
-#elif (NET_4_0)
+#if FRAMEWORK_4_5_OR_ABOVE
+[assembly: AssemblyTitle("Apache log4net for .NET Framework 4.5")]
+#elif FRAMEWORK_4_0_OR_ABOVE
#if CLIENT_PROFILE
[assembly: AssemblyTitle("Apache log4net for .NET Framework 4.0 Client Profile")]
#else
@@ -71,26 +62,10 @@
#else
[assembly: AssemblyTitle("Apache log4net for .NET Framework 2.0")]
#endif // Client Profile
-#elif (NETCF_1_0)
-[assembly: AssemblyTitle("Apache log4net for .NET Compact Framework 1.0")]
#elif (NETCF_2_0)
[assembly: AssemblyTitle("Apache log4net for .NET Compact Framework 2.0")]
-#elif (MONO_1_0)
-[assembly: AssemblyTitle("Apache log4net for Mono 1.0")]
#elif (MONO_2_0)
[assembly: AssemblyTitle("Apache log4net for Mono 2.0")]
-#elif (SSCLI_1_0)
-[assembly: AssemblyTitle("Apache log4net for Shared Source CLI 1.0")]
-#elif (CLI_1_0)
-[assembly: AssemblyTitle("Apache log4net for CLI Compatible Frameworks")]
-#elif (NET)
-[assembly: AssemblyTitle("Apache log4net for .NET Framework")]
-#elif (NETCF)
-[assembly: AssemblyTitle("Apache log4net for .NET Compact Framework")]
-#elif (MONO)
-[assembly: AssemblyTitle("Apache log4net for Mono")]
-#elif (SSCLI)
-[assembly: AssemblyTitle("Apache log4net for Shared Source CLI")]
#else
[assembly: AssemblyTitle("Apache log4net")]
#endif
@@ -105,35 +80,3 @@
[assembly: AssemblyDefaultAlias("log4net")]
[assembly: AssemblyCulture("")]
-//
-// In order to sign your assembly you must specify a key to use. Refer to the
-// Microsoft .NET Framework documentation for more information on assembly signing.
-//
-// Use the attributes below to control which key is used for signing.
-//
-// Notes:
-// (*) If no key is specified, the assembly is not signed.
-// (*) KeyName refers to a key that has been installed in the Crypto Service
-// Provider (CSP) on your machine. KeyFile refers to a file which contains
-// a key.
-// (*) If the KeyFile and the KeyName values are both specified, the
-// following processing occurs:
-// (1) If the KeyName can be found in the CSP, that key is used.
-// (2) If the KeyName does not exist and the KeyFile does exist, the key
-// in the KeyFile is installed into the CSP and used.
-// (*) In order to create a KeyFile, you can use the sn.exe (Strong Name) utility.
-// When specifying the KeyFile, the location of the KeyFile should be
-// relative to the project output directory which is
-// %Project Directory%\obj\<configuration>. For example, if your KeyFile is
-// located in the project directory, you would specify the AssemblyKeyFile
-// attribute as [assembly: AssemblyKeyFile("..\\..\\mykey.snk")]
-// (*) Delay Signing is an advanced option - see the Microsoft .NET Framework
-// documentation for more information on this.
-//
-#if STRONG && (CLI_1_0 || NET_1_0 || NET_1_1 || NETCF_1_0 || SSCLI)
-[assembly: AssemblyDelaySign(false)]
-[assembly: AssemblyKeyFile(@"..\..\..\log4net.snk")]
-#endif
-// We do not use a CSP key for strong naming
-// [assembly: AssemblyKeyName("")]
-
diff --git a/src/AssemblyVersionInfo.cs b/src/AssemblyVersionInfo.cs
index 56e0d06..906e645 100644
--- a/src/AssemblyVersionInfo.cs
+++ b/src/AssemblyVersionInfo.cs
@@ -28,13 +28,11 @@
// You can specify all the values or you can default the Revision and Build Numbers
// by using the '*' as shown below:
-[assembly: System.Reflection.AssemblyVersion("1.2.13.0")]
-[assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.2")]
+[assembly: System.Reflection.AssemblyVersion("1.3.0.0")]
+[assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.3")]
#if !NETCF
-#if !SSCLI
-[assembly: System.Reflection.AssemblyFileVersion("1.2.13.0")]
-#endif
+[assembly: System.Reflection.AssemblyFileVersion("1.3.0.0")]
#endif
//
diff --git a/src/Config/DOMConfigurator.cs b/src/Config/DOMConfigurator.cs
index 54551af..72a5b68 100644
--- a/src/Config/DOMConfigurator.cs
+++ b/src/Config/DOMConfigurator.cs
@@ -287,7 +287,7 @@ static public void Configure(ILoggerRepository repository, Stream configStream)
#region ConfigureAndWatch static methods
-#if (!NETCF && !SSCLI)
+#if !NETCF
/// <summary>
/// Configures log4net using the file specified, monitors the file for changes
diff --git a/src/Config/XmlConfigurator.cs b/src/Config/XmlConfigurator.cs
index 88621b0..084fdc2 100644
--- a/src/Config/XmlConfigurator.cs
+++ b/src/Config/XmlConfigurator.cs
@@ -639,7 +639,6 @@ static private void InternalConfigure(ILoggerRepository repository, Uri configUr
if (configRequest != null)
{
-#if !NETCF_1_0
// authentication may be required, set client to use default credentials
try
{
@@ -649,7 +648,7 @@ static private void InternalConfigure(ILoggerRepository repository, Uri configUr
{
// ignore security exception
}
-#endif
+
try
{
WebResponse response = configRequest.GetResponse();
@@ -785,7 +784,7 @@ static private void InternalConfigure(ILoggerRepository repository, Stream confi
#region ConfigureAndWatch static methods
-#if (!NETCF && !SSCLI)
+#if !NETCF
/// <summary>
/// Configures log4net using the file specified, monitors the file for changes
@@ -906,7 +905,7 @@ static private void InternalConfigureAndWatch(ILoggerRepository repository, File
#region ConfigureAndWatchHandler
-#if (!NETCF && !SSCLI)
+#if !NETCF
/// <summary>
/// Class used to watch config files.
/// </summary>
diff --git a/src/Config/XmlConfiguratorAttribute.cs b/src/Config/XmlConfiguratorAttribute.cs
index 6c3ea3e..ec38967 100644
--- a/src/Config/XmlConfiguratorAttribute.cs
+++ b/src/Config/XmlConfiguratorAttribute.cs
@@ -168,9 +168,6 @@ public string ConfigFileExtension
/// from a web server the config file may not reside on the local disk
/// and therefore it may not be able to watch it.
/// </para>
- /// <note>
- /// Watching configuration is not supported on the SSCLI.
- /// </note>
/// </remarks>
public bool Watch
{
@@ -313,13 +310,6 @@ private void ConfigureFromFile(Assembly sourceAssembly, ILoggerRepository target
/// <param name="configFile">the FileInfo pointing to the config file</param>
private void ConfigureFromFile(ILoggerRepository targetRepository, FileInfo configFile)
{
-#if (SSCLI)
- if (m_configureAndWatch)
- {
- LogLog.Warn(declaringType, "XmlConfiguratorAttribute: Unable to watch config file not supported on SSCLI");
- }
- XmlConfigurator.Configure(targetRepository, configFile);
-#else
// Do we configure just once or do we configure and then watch?
if (m_configureAndWatch)
{
@@ -329,7 +319,6 @@ private void ConfigureFromFile(ILoggerRepository targetRepository, FileInfo conf
{
XmlConfigurator.Configure(targetRepository, configFile);
}
-#endif
}
/// <summary>
diff --git a/src/Core/DefaultRepositorySelector.cs b/src/Core/DefaultRepositorySelector.cs
index 09d46cc..d374e5e 100644
--- a/src/Core/DefaultRepositorySelector.cs
+++ b/src/Core/DefaultRepositorySelector.cs
@@ -705,7 +705,7 @@ private void ConfigureRepository(Assembly assembly, ILoggerRepository repository
// Determine whether to watch the file or not based on an app setting value:
bool watchRepositoryConfigFile = false;
-#if NET_2_0 || MONO_2_0
+#if !NETCF
Boolean.TryParse(SystemInfo.GetAppSetting("log4net.Config.Watch"), out watchRepositoryConfigFile);
#else
{
diff --git a/src/Core/LoggerManager.cs b/src/Core/LoggerManager.cs
index 9a3afed..710fa91 100644
--- a/src/Core/LoggerManager.cs
+++ b/src/Core/LoggerManager.cs
@@ -805,9 +805,7 @@ private static string GetVersionInfo()
sb.Append("log4net assembly [").Append(myAssembly.FullName).Append("]. ");
sb.Append("Loaded from [").Append(SystemInfo.AssemblyLocationInfo(myAssembly)).Append("]. ");
sb.Append("(.NET Runtime [").Append(Environment.Version.ToString()).Append("]");
-#if (!SSCLI)
sb.Append(" on ").Append(Environment.OSVersion.ToString());
-#endif
sb.Append(")");
return sb.ToString();
}
diff --git a/src/Core/LoggingEvent.cs b/src/Core/LoggingEvent.cs
index 6c551aa..79e5d27 100644
--- a/src/Core/LoggingEvent.cs
+++ b/src/Core/LoggingEvent.cs
@@ -828,7 +828,7 @@ public string UserName
{
if (m_data.UserName == null && this.m_cacheUpdatable)
{
-#if (NETCF || SSCLI)
+#if NETCF
// On compact framework there's no notion of current Windows user
m_data.UserName = SystemInfo.NotAvailableText;
#else
@@ -876,7 +876,7 @@ public string Identity
{
if (m_data.Identity == null && this.m_cacheUpdatable)
{
-#if (NETCF || SSCLI)
+#if NETCF
// On compact framework there's no notion of current thread principals
m_data.Identity = SystemInfo.NotAvailableText;
#else
diff --git a/src/DateFormatter/AbsoluteTimeDateFormatter.cs b/src/DateFormatter/AbsoluteTimeDateFormatter.cs
index 1174107..8433020 100644
--- a/src/DateFormatter/AbsoluteTimeDateFormatter.cs
+++ b/src/DateFormatter/AbsoluteTimeDateFormatter.cs
@@ -140,11 +140,6 @@ virtual public void FormatDate(DateTime dateToFormat, TextWriter writer)
// Render the string buffer to a string
timeString = s_lastTimeBuf.ToString();
-#if NET_1_1
- // Ensure that the above string is written into the variable NOW on all threads.
- // This is only required on multiprocessor machines with weak memeory models
- System.Threading.Thread.MemoryBarrier();
-#endif
// Store the time as a string (we only have to do this once per second)
s_lastTimeStrings[GetType()] = timeString;
s_lastTimeToTheSecond = currentTimeToTheSecond;
diff --git a/src/Layout/Pattern/AspNetCachePatternConverter.cs b/src/Layout/Pattern/AspNetCachePatternConverter.cs
index 4452a5b..39aaab6 100644
--- a/src/Layout/Pattern/AspNetCachePatternConverter.cs
+++ b/src/Layout/Pattern/AspNetCachePatternConverter.cs
@@ -17,9 +17,8 @@
//
#endregion
-// .NET Compact Framework 1.0 has no support for ASP.NET
-// SSCLI 1.0 has no support for ASP.NET
-#if !NETCF && !SSCLI && !CLIENT_PROFILE
+// .NET Compact Framework has no support for ASP.NET
+#if !NETCF && !CLIENT_PROFILE
using System.IO;
using System.Web;
diff --git a/src/Layout/Pattern/AspNetContextPatternConverter.cs b/src/Layout/Pattern/AspNetContextPatternConverter.cs
index 61a9e17..9a6e674 100644
--- a/src/Layout/Pattern/AspNetContextPatternConverter.cs
+++ b/src/Layout/Pattern/AspNetContextPatternConverter.cs
@@ -17,9 +17,8 @@
//
#endregion
-// .NET Compact Framework 1.0 has no support for ASP.NET
-// SSCLI 1.0 has no support for ASP.NET
-#if !NETCF && !SSCLI && !CLIENT_PROFILE
+// .NET Compact Framework has no support for ASP.NET
+#if !NETCF && !CLIENT_PROFILE
using System.IO;
using System.Web;
diff --git a/src/Layout/Pattern/AspNetPatternConverter.cs b/src/Layout/Pattern/AspNetPatternConverter.cs
index 7201ecd..d16b5b3 100644
--- a/src/Layout/Pattern/AspNetPatternConverter.cs
+++ b/src/Layout/Pattern/AspNetPatternConverter.cs
@@ -17,9 +17,8 @@
//
#endregion
-// .NET Compact Framework 1.0 has no support for ASP.NET
-// SSCLI 1.0 has no support for ASP.NET
-#if !NETCF && !SSCLI && !CLIENT_PROFILE
+// .NET Compact Framework has no support for ASP.NET
+#if !NETCF && !CLIENT_PROFILE
using System.IO;
using System.Web;
diff --git a/src/Layout/Pattern/AspNetRequestPatternConverter.cs b/src/Layout/Pattern/AspNetRequestPatternConverter.cs
index ca810f6..c83c475 100644
--- a/src/Layout/Pattern/AspNetRequestPatternConverter.cs
+++ b/src/Layout/Pattern/AspNetRequestPatternConverter.cs
@@ -17,9 +17,8 @@
//
#endregion
-// .NET Compact Framework 1.0 has no support for ASP.NET
-// SSCLI 1.0 has no support for ASP.NET
-#if !NETCF && !SSCLI && !CLIENT_PROFILE
+// .NET Compact Framework has no support for ASP.NET
+#if !NETCF && !CLIENT_PROFILE
using System.IO;
using System.Web;
diff --git a/src/Layout/Pattern/AspNetSessionPatternConverter.cs b/src/Layout/Pattern/AspNetSessionPatternConverter.cs
index f50ad8a..782ddb9 100644
--- a/src/Layout/Pattern/AspNetSessionPatternConverter.cs
+++ b/src/Layout/Pattern/AspNetSessionPatternConverter.cs
@@ -17,9 +17,8 @@
//
#endregion
-// .NET Compact Framework 1.0 has no support for ASP.NET
-// SSCLI 1.0 has no support for ASP.NET
-#if !NETCF && !SSCLI && !CLIENT_PROFILE
+// .NET Compact Framework has no support for ASP.NET
+#if !NETCF && !CLIENT_PROFILE
using System.IO;
using System.Web;
diff --git a/src/Layout/PatternLayout.cs b/src/Layout/PatternLayout.cs
index 9e15921..d7dcaa6 100644
--- a/src/Layout/PatternLayout.cs
+++ b/src/Layout/PatternLayout.cs
@@ -859,9 +859,8 @@ static PatternLayout()
s_globalRulesRegistry.Add("newline", typeof(NewLinePatternConverter));
s_globalRulesRegistry.Add("n", typeof(NewLinePatternConverter));
-// .NET Compact Framework 1.0 has no support for ASP.NET
-// SSCLI 1.0 has no support for ASP.NET
-#if !NETCF && !SSCLI && !CLIENT_PROFILE
+// .NET Compact Framework has no support for ASP.NET
+#if !NETCF && !CLIENT_PROFILE
s_globalRulesRegistry.Add("aspnet-cache", typeof(AspNetCachePatternConverter));
s_globalRulesRegistry.Add("aspnet-context", typeof(AspNetContextPatternConverter));
s_globalRulesRegistry.Add("aspnet-request", typeof(AspNetRequestPatternConverter));
diff --git a/src/Layout/XMLLayout.cs b/src/Layout/XMLLayout.cs
index 6d8e432..cb704cf 100644
--- a/src/Layout/XMLLayout.cs
+++ b/src/Layout/XMLLayout.cs
@@ -220,11 +220,7 @@ override protected void FormatXml(XmlWriter writer, LoggingEvent loggingEvent)
writer.WriteStartElement(m_elmEvent);
writer.WriteAttributeString(ATTR_LOGGER, loggingEvent.LoggerName);
-#if NET_2_0 || NETCF_2_0 || MONO_2_0
writer.WriteAttributeString(ATTR_TIMESTAMP, XmlConvert.ToString(loggingEvent.TimeStamp, XmlDateTimeSerializationMode.Local));
-#else
- writer.WriteAttributeString(ATTR_TIMESTAMP, XmlConvert.ToString(loggingEvent.TimeStamp));
-#endif
writer.WriteAttributeString(ATTR_LEVEL, loggingEvent.Level.DisplayName);
writer.WriteAttributeString(ATTR_THREAD, loggingEvent.ThreadName);
diff --git a/src/Log4netAssemblyInfo.cs b/src/Log4netAssemblyInfo.cs
index 08ee5b3..40ad74c 100644
--- a/src/Log4netAssemblyInfo.cs
+++ b/src/Log4netAssemblyInfo.cs
@@ -28,31 +28,21 @@ public sealed class AssemblyInfo {
public const string Version = "1.2.13";
/// <summary>Version of the framework targeted</summary>
-#if NET_1_1
- public const decimal TargetFrameworkVersion = 1.1M;
-#elif NET_4_0
+#if NET_4_0
public const decimal TargetFrameworkVersion = 4.0M;
-#elif NET_2_0 || NETCF_2_0 || MONO_2_0
-#if !CLIENT_PROFILE
+#elif !CLIENT_PROFILE
public const decimal TargetFrameworkVersion = 2.0M;
#else
public const decimal TargetFrameworkVersion = 3.5M;
-#endif // Client Profile
-#else
- public const decimal TargetFrameworkVersion = 1.0M;
#endif
/// <summary>Type of framework targeted</summary>
-#if CLI
- public const string TargetFramework = "CLI Compatible Frameworks";
-#elif NET
+#if NET
public const string TargetFramework = ".NET Framework";
#elif NETCF
public const string TargetFramework = ".NET Compact Framework";
#elif MONO
public const string TargetFramework = "Mono";
-#elif SSCLI
- public const string TargetFramework = "Shared Source CLI";
#else
public const string TargetFramework = "Unknown";
#endif
diff --git a/src/LogicalThreadContext.cs b/src/LogicalThreadContext.cs
index d23e4fa..40357c4 100644
--- a/src/LogicalThreadContext.cs
+++ b/src/LogicalThreadContext.cs
@@ -125,7 +125,7 @@ public static LogicalThreadContextProperties Properties
/// The logical thread stacks.
/// </para>
/// </remarks>
- public static ThreadContextStacks Stacks
+ public static LogicalThreadContextStacks Stacks
{
get { return s_stacks; }
}
@@ -142,7 +142,7 @@ public static ThreadContextStacks Stacks
/// <summary>
/// The thread context stacks instance
/// </summary>
- private readonly static ThreadContextStacks s_stacks = new ThreadContextStacks(s_properties);
+ private readonly static LogicalThreadContextStacks s_stacks = new LogicalThreadContextStacks(s_properties);
#endregion Private Static Fields
}
diff --git a/src/NDC.cs b/src/NDC.cs
index 8fd3d92..b54b1d1 100644
--- a/src/NDC.cs
+++ b/src/NDC.cs
@@ -20,10 +20,6 @@
using System;
using System.Collections;
-#if NETCF_1_0
-using Stack = log4net.Util.ThreadContextStack.Stack;
-#endif
-
namespace log4net
{
/// <summary>
diff --git a/src/Repository/Hierarchy/Logger.cs b/src/Repository/Hierarchy/Logger.cs
index f1013d0..d4d3eb1 100644
--- a/src/Repository/Hierarchy/Logger.cs
+++ b/src/Repository/Hierarchy/Logger.cs
@@ -432,7 +432,7 @@ virtual public void Log(Type callerStackBoundaryDeclaringType, Level level, obje
{
log4net.Util.LogLog.Error(declaringType, "Exception while logging", ex);
}
-#if !NET_2_0 && !MONO_2_0
+#if NETCF
catch
{
log4net.Util.LogLog.Error(declaringType, "Exception while logging");
@@ -469,7 +469,7 @@ virtual public void Log(LoggingEvent logEvent)
{
log4net.Util.LogLog.Error(declaringType, "Exception while logging", ex);
}
-#if !NET_2_0 && !MONO_2_0
+#if NETCF
catch
{
log4net.Util.LogLog.Error(declaringType, "Exception while logging");
@@ -509,7 +509,7 @@ virtual public bool IsEnabledFor(Level level)
{
log4net.Util.LogLog.Error(declaringType, "Exception while logging", ex);
}
-#if !NET_2_0 && !MONO_2_0
+#if NETCF
catch
{
log4net.Util.LogLog.Error(declaringType, "Exception while logging");
diff --git a/src/Util/LogicalThreadContextProperties.cs b/src/Util/LogicalThreadContextProperties.cs
index ab40b91..4b92ed0 100644
--- a/src/Util/LogicalThreadContextProperties.cs
+++ b/src/Util/LogicalThreadContextProperties.cs
@@ -100,7 +100,12 @@ internal LogicalThreadContextProperties()
set
{
// Force the dictionary to be created
- GetProperties(true)[key] = value;
+ var props = GetProperties(true);
+ // Reason for cloning the dictionary below: object instances set on the CallContext
+ // need to be immutable to correctly flow through async/await
+ var immutableProps = new PropertiesDictionary(props);
+ immutableProps[key] = value;
+ SetCallContextData(immutableProps);
}
}
@@ -122,7 +127,9 @@ public void Remove(string key)
PropertiesDictionary dictionary = GetProperties(false);
if (dictionary != null)
{
- dictionary.Remove(key);
+ var immutableProps = new PropertiesDictionary(dictionary);
+ immutableProps.Remove(key);
+ SetCallContextData(immutableProps);
}
}
@@ -139,7 +146,8 @@ public void Clear()
PropertiesDictionary dictionary = GetProperties(false);
if (dictionary != null)
{
- dictionary.Clear();
+ var immutableProps = new PropertiesDictionary();
+ SetCallContextData(immutableProps);
}
}
@@ -208,7 +216,7 @@ internal PropertiesDictionary GetProperties(bool create)
#endif
private static PropertiesDictionary GetCallContextData()
{
-#if NET_2_0 || MONO_2_0
+#if !NETCF
return CallContext.LogicalGetData(c_SlotName) as PropertiesDictionary;
#else
return CallContext.GetData(c_SlotName) as PropertiesDictionary;
@@ -229,7 +237,7 @@ private static PropertiesDictionary GetCallContextData()
#endif
private static void SetCallContextData(PropertiesDictionary properties)
{
-#if NET_2_0 || MONO_2_0
+#if !NETCF
CallContext.LogicalSetData(c_SlotName, properties);
#else
CallContext.SetData(c_SlotName, properties);
diff --git a/src/Util/LogicalThreadContextStack.cs b/src/Util/LogicalThreadContextStack.cs
new file mode 100644
index 0000000..59a5f42
--- /dev/null
+++ b/src/Util/LogicalThreadContextStack.cs
@@ -0,0 +1,405 @@
+#region Apache License
+//
+// Licensed to the Apache Software Foundation (ASF) under one or more
+// contributor license agreements. See the NOTICE file distributed with
+// this work for additional information regarding copyright ownership.
+// The ASF licenses this file to you under the Apache License, Version 2.0
+// (the "License"); you may not use this file except in compliance with
+// the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+#endregion
+
+using System;
+using System.Collections;
+
+using log4net.Core;
+
+namespace log4net.Util
+{
+ /// <summary>
+ /// Implementation of Stack for the <see cref="log4net.LogicalThreadContext"/>
+ /// </summary>
+ /// <remarks>
+ /// <para>
+ /// Implementation of Stack for the <see cref="log4net.LogicalThreadContext"/>
+ /// </para>
+ /// </remarks>
+ /// <author>Nicko Cadell</author>
+ public sealed class LogicalThreadContextStack : IFixingRequired
+ {
+ #region Private Instance Fields
+
+ /// <summary>
+ /// The stack store.
+ /// </summary>
+ private Stack m_stack = new Stack();
+
+ /// <summary>
+ /// The name of this <see cref="log4net.LogicalThreadContextStack"/> within the
+ /// <see cref="log4net.LogicalThreadContextProperties"/>.
+ /// </summary>
+ private string m_propertyKey;
+
+ /// <summary>
+ /// The callback used to let the <see cref="log4net.LogicalThreadContextStacks"/> register a
+ /// new instance of a <see cref="log4net.LogicalThreadContextStack"/>.
+ /// </summary>
+ private Action<string, LogicalThreadContextStack> m_registerNew;
+
+ #endregion Private Instance Fields
+
+ #region Public Instance Constructors
+
+ /// <summary>
+ /// Internal constructor
+ /// </summary>
+ /// <remarks>
+ /// <para>
+ /// Initializes a new instance of the <see cref="LogicalThreadContextStack" /> class.
+ /// </para>
+ /// </remarks>
+ internal LogicalThreadContextStack(string propertyKey, Action<string, LogicalThreadContextStack> registerNew)
+ {
+ m_propertyKey = propertyKey;
+ m_registerNew = registerNew;
+ }
+
+ #endregion Public Instance Constructors
+
+ #region Public Properties
+
+ /// <summary>
+ /// The number of messages in the stack
+ /// </summary>
+ /// <value>
+ /// The current number of messages in the stack
+ /// </value>
+ /// <remarks>
+ /// <para>
+ /// The current number of messages in the stack. That is
+ /// the number of times <see cref="Push"/> has been called
+ /// minus the number of times <see cref="Pop"/> has been called.
+ /// </para>
+ /// </remarks>
+ public int Count
+ {
+ get { return m_stack.Count; }
+ }
+
+ #endregion // Public Properties
+
+ #region Public Methods
+
+ /// <summary>
+ /// Clears all the contextual information held in this stack.
+ /// </summary>
+ /// <remarks>
+ /// <para>
+ /// Clears all the contextual information held in this stack.
+ /// Only call this if you think that this thread is being reused after
+ /// a previous call execution which may not have completed correctly.
+ /// You do not need to use this method if you always guarantee to call
+ /// the <see cref="IDisposable.Dispose"/> method of the <see cref="IDisposable"/>
+ /// returned from <see cref="Push"/> even in exceptional circumstances,
+ /// for example by using the <c>using(log4net.LogicalThreadContext.Stacks["NDC"].Push("Stack_Message"))</c>
+ /// syntax.
+ /// </para>
+ /// </remarks>
+ public void Clear()
+ {
+ m_registerNew(m_propertyKey, new LogicalThreadContextStack(m_propertyKey, m_registerNew));
+ }
+
+ /// <summary>
+ /// Removes the top context from this stack.
+ /// </summary>
+ /// <returns>The message in the context that was removed from the top of this stack.</returns>
+ /// <remarks>
+ /// <para>
+ /// Remove the top context from this stack, and return
+ /// it to the caller. If this stack is empty then an
+ /// empty string (not <see langword="null"/>) is returned.
+ /// </para>
+ /// </remarks>
+ public string Pop()
+ {
+ // copy current stack
+ Stack stack = new Stack(new Stack(m_stack));
+ string result = "";
+ if (stack.Count > 0)
+ {
+ result = ((StackFrame)(stack.Pop())).Message;
+ }
+ m_registerNew(m_propertyKey,
+ new LogicalThreadContextStack(m_propertyKey, m_registerNew) { m_stack = stack });
+ return result;
+ }
+
+ /// <summary>
+ /// Pushes a new context message into this stack.
+ /// </summary>
+ /// <param name="message">The new context message.</param>
+ /// <returns>
+ /// An <see cref="IDisposable"/> that can be used to clean up the context stack.
+ /// </returns>
+ /// <remarks>
+ /// <para>
+ /// Pushes a new context onto this stack. An <see cref="IDisposable"/>
+ /// is returned that can be used to clean up this stack. This
+ /// can be easily combined with the <c>using</c> keyword to scope the
+ /// context.
+ /// </para>
+ /// </remarks>
+ /// <example>Simple example of using the <c>Push</c> method with the <c>using</c> keyword.
+ /// <code lang="C#">
+ /// using(log4net.LogicalThreadContext.Stacks["NDC"].Push("Stack_Message"))
+ /// {
+ /// log.Warn("This should have an ThreadContext Stack message");
+ /// }
+ /// </code>
+ /// </example>
+ public IDisposable Push(string message)
+ {
+ // do modifications on a copy
+ Stack stack = new Stack(new Stack(m_stack));
+ stack.Push(new StackFrame(message, (stack.Count > 0) ? (StackFrame)stack.Peek() : null));
+
+ var contextStack = new LogicalThreadContextStack(m_propertyKey, m_registerNew) { m_stack = stack };
+ m_registerNew(m_propertyKey, contextStack);
+ return new AutoPopStackFrame(contextStack, stack.Count - 1);
+ }
+
+ #endregion Public Methods
+
+ #region Internal Methods
+
+ /// <summary>
+ /// Gets the current context information for this stack.
+ /// </summary>
+ /// <returns>The current context information.</returns>
+ internal string GetFullMessage()
+ {
+ Stack stack = m_stack;
+ if (stack.Count > 0)
+ {
+ return ((StackFrame)(stack.Peek())).FullMessage;
+ }
+ return null;
+ }
+
+ /// <summary>
+ /// Gets and sets the internal stack used by this <see cref="LogicalThreadContextStack"/>
+ /// </summary>
+ /// <value>The internal storage stack</value>
+ /// <remarks>
+ /// <para>
+ /// This property is provided only to support backward compatability
+ /// of the <see cref="NDC"/>. Tytpically the internal stack should not
+ /// be modified.
+ /// </para>
+ /// </remarks>
+ internal Stack InternalStack
+ {
+ get { return m_stack; }
+ set { m_stack = value; }
+ }
+
+ #endregion Internal Methods
+
+ /// <summary>
+ /// Gets the current context information for this stack.
+ /// </summary>
+ /// <returns>Gets the current context information</returns>
+ /// <remarks>
+ /// <para>
+ /// Gets the current context information for this stack.
+ /// </para>
+ /// </remarks>
+ public override string ToString()
+ {
+ return GetFullMessage();
+ }
+
+ /// <summary>
+ /// Get a portable version of this object
+ /// </summary>
+ /// <returns>the portable instance of this object</returns>
+ /// <remarks>
+ /// <para>
+ /// Get a cross thread portable version of this object
+ /// </para>
+ /// </remarks>
+ object IFixingRequired.GetFixedObject()
+ {
+ return GetFullMessage();
+ }
+
+ /// <summary>
+ /// Inner class used to represent a single context frame in the stack.
+ /// </summary>
+ /// <remarks>
+ /// <para>
+ /// Inner class used to represent a single context frame in the stack.
+ /// </para>
+ /// </remarks>
+ private sealed class StackFrame
+ {
+ #region Private Instance Fields
+
+ private readonly string m_message;
+ private readonly StackFrame m_parent;
+ private string m_fullMessage = null;
+
+ #endregion
+
+ #region Internal Instance Constructors
+
+ /// <summary>
+ /// Constructor
+ /// </summary>
+ /// <param name="message">The message for this context.</param>
+ /// <param name="parent">The parent context in the chain.</param>
+ /// <remarks>
+ /// <para>
+ /// Initializes a new instance of the <see cref="StackFrame" /> class
+ /// with the specified message and parent context.
+ /// </para>
+ /// </remarks>
+ internal StackFrame(string message, StackFrame parent)
+ {
+ m_message = message;
+ m_parent = parent;
+
+ if (parent == null)
+ {
+ m_fullMessage = message;
+ }
+ }
+
+ #endregion Internal Instance Constructors
+
+ #region Internal Instance Properties
+
+ /// <summary>
+ /// Get the message.
+ /// </summary>
+ /// <value>The message.</value>
+ /// <remarks>
+ /// <para>
+ /// Get the message.
+ /// </para>
+ /// </remarks>
+ internal string Message
+ {
+ get { return m_message; }
+ }
+
+ /// <summary>
+ /// Gets the full text of the context down to the root level.
+ /// </summary>
+ /// <value>
+ /// The full text of the context down to the root level.
+ /// </value>
+ /// <remarks>
+ /// <para>
+ /// Gets the full text of the context down to the root level.
+ /// </para>
+ /// </remarks>
+ internal string FullMessage
+ {
+ get
+ {
+ if (m_fullMessage == null && m_parent != null)
+ {
+ m_fullMessage = string.Concat(m_parent.FullMessage, " ", m_message);
+ }
+ return m_fullMessage;
+ }
+ }
+
+ #endregion Internal Instance Properties
+ }
+
+ /// <summary>
+ /// Struct returned from the <see cref="LogicalThreadContextStack.Push"/> method.
+ /// </summary>
+ /// <remarks>
+ /// <para>
+ /// This struct implements the <see cref="IDisposable"/> and is designed to be used
+ /// with the <see langword="using"/> pattern to remove the stack frame at the end of the scope.
+ /// </para>
+ /// </remarks>
+ private struct AutoPopStackFrame : IDisposable
+ {
+ #region Private Instance Fields
+
+ /// <summary>
+ /// The depth to trim the stack to when this instance is disposed
+ /// </summary>
+ private int m_frameDepth;
+
+ /// <summary>
+ /// The outer LogicalThreadContextStack.
+ /// </summary>
+ private LogicalThreadContextStack m_logicalThreadContextStack;
+
+ #endregion Private Instance Fields
+
+ #region Internal Instance Constructors
+
+ /// <summary>
+ /// Constructor
+ /// </summary>
+ /// <param name="frameStack">The internal stack used by the ThreadContextStack.</param>
+ /// <param name="frameDepth">The depth to return the stack to when this object is disposed.</param>
+ /// <remarks>
+ /// <para>
+ /// Initializes a new instance of the <see cref="AutoPopStackFrame" /> class with
+ /// the specified stack and return depth.
+ /// </para>
+ /// </remarks>
+ internal AutoPopStackFrame(LogicalThreadContextStack logicalThreadContextStack, int frameDepth)
+ {
+ m_frameDepth = frameDepth;
+ m_logicalThreadContextStack = logicalThreadContextStack;
+ }
+
+ #endregion Internal Instance Constructors
+
+ #region Implementation of IDisposable
+
+ /// <summary>
+ /// Returns the stack to the correct depth.
+ /// </summary>
+ /// <remarks>
+ /// <para>
+ /// Returns the stack to the correct depth.
+ /// </para>
+ /// </remarks>
+ public void Dispose()
+ {
+ if (m_frameDepth >= 0 && m_logicalThreadContextStack.m_stack != null)
+ {
+ Stack stack = new Stack(new Stack(m_logicalThreadContextStack.m_stack));
+ while (stack.Count > m_frameDepth)
+ {
+ stack.Pop();
+ }
+ m_logicalThreadContextStack.m_registerNew(m_logicalThreadContextStack.m_propertyKey,
+ new LogicalThreadContextStack(m_logicalThreadContextStack.m_propertyKey, m_logicalThreadContextStack.m_registerNew) { m_stack = stack });
+ }
+ }
+
+ #endregion Implementation of IDisposable
+ }
+
+ }
+}
\ No newline at end of file
diff --git a/src/Util/LogicalThreadContextStacks.cs b/src/Util/LogicalThreadContextStacks.cs
new file mode 100644
index 0000000..834f877
--- /dev/null
+++ b/src/Util/LogicalThreadContextStacks.cs
@@ -0,0 +1,132 @@
+#region Apache License
+//
+// Licensed to the Apache Software Foundation (ASF) under one or more
+// contributor license agreements. See the NOTICE file distributed with
+// this work for additional information regarding copyright ownership.
+// The ASF licenses this file to you under the Apache License, Version 2.0
+// (the "License"); you may not use this file except in compliance with
+// the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+#endregion
+
+using System;
+using System.Collections;
+
+namespace log4net.Util
+{
+ /// <summary>
+ /// Implementation of Stacks collection for the <see cref="log4net.LogicalThreadContext"/>
+ /// </summary>
+ /// <remarks>
+ /// <para>
+ /// Implementation of Stacks collection for the <see cref="log4net.LogicalThreadContext"/>
+ /// </para>
+ /// </remarks>
+ /// <author>Nicko Cadell</author>
+ public sealed class LogicalThreadContextStacks
+ {
+ private readonly LogicalThreadContextProperties m_properties;
+
+ #region Public Instance Constructors
+
+ /// <summary>
+ /// Internal constructor
+ /// </summary>
+ /// <remarks>
+ /// <para>
+ /// Initializes a new instance of the <see cref="ThreadContextStacks" /> class.
+ /// </para>
+ /// </remarks>
+ internal LogicalThreadContextStacks(LogicalThreadContextProperties properties)
+ {
+ m_properties = properties;
+ }
+
+ #endregion Public Instance Constructors
+
+ #region Public Instance Properties
+
+ /// <summary>
+ /// Gets the named thread context stack
+ /// </summary>
+ /// <value>
+ /// The named stack
+ /// </value>
+ /// <remarks>
+ /// <para>
+ /// Gets the named thread context stack
+ /// </para>
+ /// </remarks>
+ public LogicalThreadContextStack this[string key]
+ {
+ get
+ {
+ LogicalThreadContextStack stack = null;
+
+ object propertyValue = m_properties[key];
+ if (propertyValue == null)
+ {
+ // Stack does not exist, create
+ stack = new LogicalThreadContextStack(key, registerNew);
+ m_properties[key] = stack;
+ }
+ else
+ {
+ // Look for existing stack
+ stack = propertyValue as LogicalThreadContextStack;
+ if (stack == null)
+ {
+ // Property is not set to a stack!
+ string propertyValueString = SystemInfo.NullText;
+
+ try
+ {
+ propertyValueString = propertyValue.ToString();
+ }
+ catch
+ {
+ }
+
+ LogLog.Error(declaringType, "ThreadContextStacks: Request for stack named [" + key + "] failed because a property with the same name exists which is a [" + propertyValue.GetType().Name + "] with value [" + propertyValueString + "]");
+
+ stack = new LogicalThreadContextStack(key, registerNew);
+ }
+ }
+
+ return stack;
+ }
+ }
+
+ #endregion Public Instance Properties
+
+ #region Private Instance Fields
+
+ private void registerNew(string stackName, LogicalThreadContextStack stack)
+ {
+ m_properties[stackName] = stack;
+ }
+
+ #endregion Private Instance Fields
+
+ #region Private Static Fields
+
+ /// <summary>
+ /// The fully qualified type of the ThreadContextStacks class.
+ /// </summary>
+ /// <remarks>
+ /// Used by the internal logger to record the Type of the
+ /// log message.
+ /// </remarks>
+ private readonly static Type declaringType = typeof(LogicalThreadContextStacks);
+
+ #endregion Private Static Fields
+ }
+}
diff --git a/src/Util/NativeError.cs b/src/Util/NativeError.cs
index 5776c87..f1cbb63 100644
--- a/src/Util/NativeError.cs
+++ b/src/Util/NativeError.cs
@@ -17,13 +17,6 @@
//
#endregion
-// MONO 1.0 has no support for Win32 Error APIs
-#if !MONO
-// SSCLI 1.0 has no support for Win32 Error APIs
-#if !SSCLI
-// We don't want framework or platform specific code in the CLI version of log4net
-#if !CLI_1_0
-
using System;
using System.Globalization;
using System.Runtime.InteropServices;
@@ -284,7 +277,3 @@ public override string ToString()
#endregion
}
}
-
-#endif // !CLI_1_0
-#endif // !SSCLI
-#endif // !MONO
diff --git a/src/Util/PatternStringConverters/IdentityPatternConverter.cs b/src/Util/PatternStringConverters/IdentityPatternConverter.cs
index 5f83c76..9ea58d7 100644
--- a/src/Util/PatternStringConverters/IdentityPatternConverter.cs
+++ b/src/Util/PatternStringConverters/IdentityPatternConverter.cs
@@ -48,7 +48,7 @@ internal sealed class IdentityPatternConverter : PatternConverter
/// </remarks>
override protected void Convert(TextWriter writer, object state)
{
-#if (NETCF || SSCLI)
+#if NETCF
// On compact framework there's no notion of current thread principals
writer.Write( SystemInfo.NotAvailableText );
#else
diff --git a/src/Util/PatternStringConverters/ProcessIdPatternConverter.cs b/src/Util/PatternStringConverters/ProcessIdPatternConverter.cs
index cf5df78..aaeb8ad 100644
--- a/src/Util/PatternStringConverters/ProcessIdPatternConverter.cs
+++ b/src/Util/PatternStringConverters/ProcessIdPatternConverter.cs
@@ -51,7 +51,7 @@ internal sealed class ProcessIdPatternConverter : PatternConverter
#endif
override protected void Convert(TextWriter writer, object state)
{
-#if (NETCF || SSCLI)
+#if NETCF
// On compact framework there is no System.Diagnostics.Process class
writer.Write( SystemInfo.NotAvailableText );
#else
diff --git a/src/Util/PatternStringConverters/UserNamePatternConverter.cs b/src/Util/PatternStringConverters/UserNamePatternConverter.cs
index 921ee24..b26ee76 100644
--- a/src/Util/PatternStringConverters/UserNamePatternConverter.cs
+++ b/src/Util/PatternStringConverters/UserNamePatternConverter.cs
@@ -48,7 +48,7 @@ internal sealed class UserNamePatternConverter : PatternConverter
/// </remarks>
override protected void Convert(TextWriter writer, object state)
{
-#if (NETCF || SSCLI)
+#if NETCF
// On compact framework there's no notion of current Windows user
writer.Write( SystemInfo.NotAvailableText );
#else
diff --git a/src/Util/ReadOnlyPropertiesDictionary.cs b/src/Util/ReadOnlyPropertiesDictionary.cs
index 519d4d7..3bd57c6 100644
--- a/src/Util/ReadOnlyPropertiesDictionary.cs
+++ b/src/Util/ReadOnlyPropertiesDictionary.cs
@@ -52,7 +52,7 @@ public class ReadOnlyPropertiesDictionary : IDictionary
/// <summary>
/// The Hashtable used to store the properties data
/// </summary>
- private Hashtable m_hashtable = new Hashtable();
+ private readonly Hashtable m_hashtable = new Hashtable();
#endregion Private Instance Fields
@@ -210,7 +210,7 @@ protected Hashtable InnerHashtable
#endif
public virtual void GetObjectData(SerializationInfo info, StreamingContext context)
{
- foreach(DictionaryEntry entry in InnerHashtable)
+ foreach(DictionaryEntry entry in InnerHashtable.Clone() as IDictionary)
{
string entryKey = entry.Key as string;
object entryValue = entry.Value;
diff --git a/src/Util/SystemInfo.cs b/src/Util/SystemInfo.cs
index d61d5c9..0022cb9 100644
--- a/src/Util/SystemInfo.cs
+++ b/src/Util/SystemInfo.cs
@@ -223,13 +223,7 @@ public static int CurrentThreadId
{
get
{
-#if NETCF_1_0
- return System.Threading.Thread.CurrentThread.GetHashCode();
-#elif NET_2_0 || NETCF_2_0 || MONO_2_0
return System.Threading.Thread.CurrentThread.ManagedThreadId;
-#else
- return AppDomain.GetCurrentThreadId();
-#endif
}
}
@@ -283,7 +277,7 @@ public static string HostName
{
try
{
-#if (!SSCLI && !NETCF)
+#if !NETCF
s_hostName = Environment.MachineName;
#endif
}
@@ -740,11 +734,7 @@ public static Type GetTypeFromString(Assembly relativeAssembly, string typeName,
/// </remarks>
public static Guid NewGuid()
{
-#if NETCF_1_0
- return PocketGuid.NewGuid();
-#else
return Guid.NewGuid();
-#endif
}
/// <summary>
@@ -768,9 +758,7 @@ public static Guid NewGuid()
/// </remarks>
public static ArgumentOutOfRangeException CreateArgumentOutOfRangeException(string parameterName, object actualValue, string message)
{
-#if NETCF_1_0
- return new ArgumentOutOfRangeException(message + " [param=" + parameterName + "] [value=" + actualValue + "]");
-#elif NETCF_2_0
+#if NETCF_2_0
return new ArgumentOutOfRangeException(parameterName, message + " [value=" + actualValue + "]");
#else
return new ArgumentOutOfRangeException(parameterName, actualValue, message);
@@ -1013,13 +1001,7 @@ public static string ConvertToFullPath(string path)
/// </remarks>
public static Hashtable CreateCaseInsensitiveHashtable()
{
-#if NETCF_1_0
- return new Hashtable(CaseInsensitiveHashCodeProvider.Default, CaseInsensitiveComparer.Default);
-#elif NETCF_2_0 || NET_2_0 || MONO_2_0
return new Hashtable(StringComparer.OrdinalIgnoreCase);
-#else
- return System.Collections.Specialized.CollectionsUtil.CreateCaseInsensitiveHashtable();
-#endif
}
#endregion Public Static Methods
@@ -1117,126 +1099,5 @@ private static string NativeEntryAssemblyLocation
private static DateTime s_processStartTime = DateTime.Now;
#endregion
-
- #region Compact Framework Helper Classes
-#if NETCF_1_0
- /// <summary>
- /// Generate GUIDs on the .NET Compact Framework.
- /// </summary>
- public class PocketGuid
- {
- // guid variant types
- private enum GuidVariant
- {
- ReservedNCS = 0x00,
- Standard = 0x02,
- ReservedMicrosoft = 0x06,
- ReservedFuture = 0x07
- }
-
- // guid version types
- private enum GuidVersion
- {
- TimeBased = 0x01,
- Reserved = 0x02,
- NameBased = 0x03,
- Random = 0x04
- }
-
- // constants that are used in the class
- private class Const
- {
- // number of bytes in guid
- public const int ByteArraySize = 16;
-
- // multiplex variant info
- public const int VariantByte = 8;
- public const int VariantByteMask = 0x3f;
- public const int VariantByteShift = 6;
-
- // multiplex version info
- public const int VersionByte = 7;
- public const int VersionByteMask = 0x0f;
- public const int VersionByteShift = 4;
- }
-
- // imports for the crypto api functions
- private class WinApi
- {
- public const uint PROV_RSA_FULL = 1;
- public const uint CRYPT_VERIFYCONTEXT = 0xf0000000;
-
- [DllImport("CoreDll.dll")]
- public static extern bool CryptAcquireContext(
- ref IntPtr phProv, string pszContainer, string pszProvider,
- uint dwProvType, uint dwFlags);
-
- [DllImport("CoreDll.dll")]
- public static extern bool CryptReleaseContext(
- IntPtr hProv, uint dwFlags);
-
- [DllImport("CoreDll.dll")]
- public static extern bool CryptGenRandom(
- IntPtr hProv, int dwLen, byte[] pbBuffer);
- }
-
- // all static methods
- private PocketGuid()
- {
- }
-
- /// <summary>
- /// Return a new System.Guid object.
- /// </summary>
- public static Guid NewGuid()
- {
- IntPtr hCryptProv = IntPtr.Zero;
- Guid guid = Guid.Empty;
-
- try
- {
- // holds random bits for guid
- byte[] bits = new byte[Const.ByteArraySize];
-
- // get crypto provider handle
- if (!WinApi.CryptAcquireContext(ref hCryptProv, null, null,
- WinApi.PROV_RSA_FULL, WinApi.CRYPT_VERIFYCONTEXT))
- {
- throw new SystemException(
- "Failed to acquire cryptography handle.");
- }
-
- // generate a 128 bit (16 byte) cryptographically random number
- if (!WinApi.CryptGenRandom(hCryptProv, bits.Length, bits))
- {
- throw new SystemException(
- "Failed to generate cryptography random bytes.");
- }
-
- // set the variant
- bits[Const.VariantByte] &= Const.VariantByteMask;
- bits[Const.VariantByte] |=
- ((int)GuidVariant.Standard << Const.VariantByteShift);
-
- // set the version
- bits[Const.VersionByte] &= Const.VersionByteMask;
- bits[Const.VersionByte] |=
- ((int)GuidVersion.Random << Const.VersionByteShift);
-
- // create the new System.Guid object
- guid = new Guid(bits);
- }
- finally
- {
- // release the crypto provider handle
- if (hCryptProv != IntPtr.Zero)
- WinApi.CryptReleaseContext(hCryptProv, 0);
- }
-
- return guid;
- }
- }
-#endif
- #endregion Compact Framework Helper Classes
}
}
diff --git a/src/Util/SystemStringFormat.cs b/src/Util/SystemStringFormat.cs
index 82404b9..d7e504f 100644
--- a/src/Util/SystemStringFormat.cs
+++ b/src/Util/SystemStringFormat.cs
@@ -109,7 +109,7 @@ private static string StringFormat(IFormatProvider provider, string format, para
log4net.Util.LogLog.Warn(declaringType, "Exception while rendering format ["+format+"]", ex);
return StringFormatError(ex, format, args);
}
-#if !NET_2_0 && !MONO_2_0
+#if NETCF
catch
{
log4net.Util.LogLog.Warn(declaringType, "Exception while rendering format ["+format+"]");
@@ -148,7 +148,7 @@ private static string StringFormatError(Exception formatException, string format
log4net.Util.LogLog.Error(declaringType, "INTERNAL ERROR during StringFormat error handling", ex);
return "<log4net.Error>Exception during StringFormat. See Internal Log.</log4net.Error>";
}
-#if !NET_2_0 && !MONO_2_0
+#if NETCF
catch
{
log4net.Util.LogLog.Error(declaringType, "INTERNAL ERROR during StringFormat error handling");
@@ -210,7 +210,7 @@ private static void RenderObject(Object obj, StringBuilder buffer)
{
buffer.Append("<Exception: ").Append(ex.Message).Append(">");
}
-#if !NET_2_0 && !MONO_2_0
+#if NETCF
catch
{
buffer.Append("<Exception>");
diff --git a/src/Util/ThreadContextStack.cs b/src/Util/ThreadContextStack.cs
index d723dca..e8a3074 100644
--- a/src/Util/ThreadContextStack.cs
+++ b/src/Util/ThreadContextStack.cs
@@ -18,10 +18,7 @@
#endregion
using System;
-
-#if !NETCF_1_0
using System.Collections;
-#endif
using log4net.Core;
@@ -380,56 +377,5 @@ public void Dispose()
#endregion Implementation of IDisposable
}
-#if NETCF_1_0
- /// <summary>
- /// Subclass of <see cref="System.Collections.Stack"/> to
- /// provide missing methods.
- /// </summary>
- /// <remarks>
- /// <para>
- /// The Compact Framework version of the <see cref="System.Collections.Stack"/>
- /// class is missing the <c>Clear</c> and <c>Clone</c> methods.
- /// This subclass adds implementations of those missing methods.
- /// </para>
- /// </remarks>
- public class Stack : System.Collections.Stack
- {
- /// <summary>
- /// Clears the stack of all elements.
- /// </summary>
- /// <remarks>
- /// <para>
- /// Clears the stack of all elements.
- /// </para>
- /// </remarks>
- public void Clear()
- {
- while(Count > 0)
- {
- Pop();
- }
- }
-
- /// <summary>
- /// Makes a shallow copy of the stack's elements.
- /// </summary>
- /// <returns>A new stack that has a shallow copy of the stack's elements.</returns>
- /// <remarks>
- /// <para>
- /// Makes a shallow copy of the stack's elements.
- /// </para>
- /// </remarks>
- public Stack Clone()
- {
- Stack res = new Stack();
- object[] items = ToArray();
- foreach(object item in items)
- {
- res.Push(item);
- }
- return res;
- }
- }
-#endif
}
}
diff --git a/src/Util/WindowsSecurityContext.cs b/src/Util/WindowsSecurityContext.cs
index 357c43d..74ebfaa 100644
--- a/src/Util/WindowsSecurityContext.cs
+++ b/src/Util/WindowsSecurityContext.cs
@@ -17,14 +17,8 @@
//
#endregion
-// .NET Compact Framework 1.0 has no support for WindowsIdentity
+// .NET Compact Framework has no support for WindowsIdentity
#if !NETCF
-// MONO 1.0 has no support for Win32 Logon APIs
-#if !MONO
-// SSCLI 1.0 has no support for Win32 Logon APIs
-#if !SSCLI
-// We don't want framework or platform specific code in the CLI version of log4net
-#if !CLI_1_0
using System;
using System.Runtime.InteropServices;
@@ -380,8 +374,5 @@ public void Dispose()
}
}
-#endif // !CLI_1_0
-#endif // !SSCLI
-#endif // !MONO
#endif // !NETCF
diff --git a/src/log4net.vs2008.csproj b/src/log4net.vs2008.csproj
index 1a227aa..51ac524 100644
--- a/src/log4net.vs2008.csproj
+++ b/src/log4net.vs2008.csproj
@@ -69,13 +69,13 @@
<ErrorReport>prompt</ErrorReport>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
- <OutputPath>..\build\bin\net\1.0\release\</OutputPath>
+ <OutputPath>..\build\bin\net\2.0\release\</OutputPath>
<AllowUnsafeBlocks>false</AllowUnsafeBlocks>
<BaseAddress>285212672</BaseAddress>
<CheckForOverflowUnderflow>false</CheckForOverflowUnderflow>
<ConfigurationOverrideFile>
</ConfigurationOverrideFile>
- <DefineConstants>TRACE;STRONG;NET;NET_1_0;</DefineConstants>
+ <DefineConstants>TRACE;STRONG;NET;NET_2_0;</DefineConstants>
<DocumentationFile>log4net.xml</DocumentationFile>
<DebugSymbols>false</DebugSymbols>
<FileAlignment>4096</FileAlignment>
diff --git a/src/log4net.vs2010.csproj b/src/log4net.vs2010.csproj
index e72a356..a67671b 100644
--- a/src/log4net.vs2010.csproj
+++ b/src/log4net.vs2010.csproj
@@ -723,9 +723,15 @@
<Compile Include="Util\ThreadContextProperties.cs">
<SubType>Code</SubType>
</Compile>
+ <Compile Include="Util\LogicalThreadContextStack.cs">
+ <SubType>Code</SubType>
+ </Compile>
<Compile Include="Util\ThreadContextStack.cs">
<SubType>Code</SubType>
</Compile>
+ <Compile Include="Util\LogicalThreadContextStacks.cs">
+ <SubType>Code</SubType>
+ </Compile>
<Compile Include="Util\ThreadContextStacks.cs">
<SubType>Code</SubType>
</Compile>
diff --git a/tests/src/Appender/RemotingAppenderTest.cs b/tests/src/Appender/RemotingAppenderTest.cs
index 376ba27..9d88e17 100644
--- a/tests/src/Appender/RemotingAppenderTest.cs
+++ b/tests/src/Appender/RemotingAppenderTest.cs
@@ -207,7 +207,7 @@ private void RegisterRemotingServerChannel()
// Setup remoting server
try
{
-#if NET_2_0 || MONO_2_0
+#if !NETCF
ChannelServices.RegisterChannel(m_remotingChannel, false);
#else
ChannelServices.RegisterChannel(m_remotingChannel);
diff --git a/tests/src/Context/LogicalThreadContextTest.cs b/tests/src/Context/LogicalThreadContextTest.cs
new file mode 100644
index 0000000..08ef245
--- /dev/null
+++ b/tests/src/Context/LogicalThreadContextTest.cs
@@ -0,0 +1,344 @@
+#region Apache License
+//
+// Licensed to the Apache Software Foundation (ASF) under one or more
+// contributor license agreements. See the NOTICE file distributed with
+// this work for additional information regarding copyright ownership.
+// The ASF licenses this file to you under the Apache License, Version 2.0
+// (the "License"); you may not use this file except in compliance with
+// the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+#endregion
+
+using System;
+using System.Threading.Tasks;
+using System.Linq;
+
+using log4net.Config;
+using log4net.Layout;
+using log4net.Repository;
+using log4net.Tests.Appender;
+using log4net.Util;
+
+using NUnit.Framework;
+
+namespace log4net.Tests.Context
+{
+#if FRAMEWORK_4_5_OR_ABOVE
+ /// <summary>
+ /// Used for internal unit testing the <see cref="LogicalThreadContext"/> class.
+ /// </summary>
+ /// <remarks>
+ /// Used for internal unit testing the <see cref="LogicalThreadContext"/> class.
+ /// </remarks>
+ [TestFixture]
+ public class LogicalThreadContextTest
+ {
+ [TearDown]
+ public void TearDown()
+ {
+ Utils.RemovePropertyFromAllContexts();
+ }
+
+ [Test]
+ public void TestLogicalThreadPropertiesPatternBasicGetSet()
+ {
+ StringAppender stringAppender = new StringAppender();
+ stringAppender.Layout = new PatternLayout("%property{" + Utils.PROPERTY_KEY + "}");
+
+ ILoggerRepository rep = LogManager.CreateRepository(Guid.NewGuid().ToString());
+ BasicConfigurator.Configure(rep, stringAppender);
+
+ ILog log1 = LogManager.GetLogger(rep.Name, "TestLogicalThreadPropertiesPattern");
+
+ log1.Info("TestMessage");
+ Assert.AreEqual(SystemInfo.NullText, stringAppender.GetString(), "Test no logical thread properties value set");
+ stringAppender.Reset();
+
+ LogicalThreadContext.Properties[Utils.PROPERTY_KEY] = "val1";
+
+ log1.Info("TestMessage");
+ Assert.AreEqual("val1", stringAppender.GetString(), "Test logical thread properties value set");
+ stringAppender.Reset();
+
+ LogicalThreadContext.Properties.Remove(Utils.PROPERTY_KEY);
+
+ log1.Info("TestMessage");
+ Assert.AreEqual(SystemInfo.NullText, stringAppender.GetString(), "Test logical thread properties value removed");
+ stringAppender.Reset();
+ }
+
+ [Test]
+ public async Task TestLogicalThreadPropertiesPatternAsyncAwait()
+ {
+ StringAppender stringAppender = new StringAppender();
+ stringAppender.Layout = new PatternLayout("%property{" + Utils.PROPERTY_KEY + "}");
+
+ ILoggerRepository rep = LogManager.CreateRepository(Guid.NewGuid().ToString());
+ BasicConfigurator.Configure(rep, stringAppender);
+
+ ILog log1 = LogManager.GetLogger(rep.Name, "TestLogicalThreadPropertiesPattern");
+
+ log1.Info("TestMessage");
+ Assert.AreEqual(SystemInfo.NullText, stringAppender.GetString(), "Test no logical thread stack value set");
+ stringAppender.Reset();
+
+ string testValueForCurrentContext = "Outer";
+ LogicalThreadContext.Properties[Utils.PROPERTY_KEY] = testValueForCurrentContext;
+
+ log1.Info("TestMessage");
+ Assert.AreEqual(testValueForCurrentContext, stringAppender.GetString(), "Test logical thread properties value set");
+ stringAppender.Reset();
+
+ var strings = await Task.WhenAll(Enumerable.Range(0, 10).Select(x => SomeWorkProperties(x.ToString())));
+
+ // strings should be ["00AA0BB0", "01AA1BB1", "02AA2BB2", ...]
+ for (int i = 0; i < strings.Length; i++)
+ {
+ Assert.AreEqual(string.Format("{0}{1}AA{1}BB{1}", testValueForCurrentContext, i), strings[i], "Test logical thread properties expected sequence");
+ }
+
+ log1.Info("TestMessage");
+ Assert.AreEqual(testValueForCurrentContext, stringAppender.GetString(), "Test logical thread properties value set");
+ stringAppender.Reset();
+
+ LogicalThreadContext.Properties.Remove(Utils.PROPERTY_KEY);
+
+ log1.Info("TestMessage");
+ Assert.AreEqual(SystemInfo.NullText, stringAppender.GetString(), "Test logical thread properties value removed");
+ stringAppender.Reset();
+ }
+
+ [Test]
+ public void TestLogicalThreadStackPattern()
+ {
+ StringAppender stringAppender = new StringAppender();
+ stringAppender.Layout = new PatternLayout("%property{" + Utils.PROPERTY_KEY + "}");
+
+ ILoggerRepository rep = LogManager.CreateRepository(Guid.NewGuid().ToString());
+ BasicConfigurator.Configure(rep, stringAppender);
+
+ ILog log1 = LogManager.GetLogger(rep.Name, "TestThreadStackPattern");
+
+ log1.Info("TestMessage");
+ Assert.AreEqual(SystemInfo.NullText, stringAppender.GetString(), "Test no logical thread stack value set");
+ stringAppender.Reset();
+
+ using (LogicalThreadContext.Stacks[Utils.PROPERTY_KEY].Push("val1"))
+ {
+ log1.Info("TestMessage");
+ Assert.AreEqual("val1", stringAppender.GetString(), "Test logical thread stack value set");
+ stringAppender.Reset();
+ }
+
+ log1.Info("TestMessage");
+ Assert.AreEqual(SystemInfo.NullText, stringAppender.GetString(), "Test logical thread stack value removed");
+ stringAppender.Reset();
+ }
+
+ [Test]
+ public void TestLogicalThreadStackPattern2()
+ {
+ StringAppender stringAppender = new StringAppender();
+ stringAppender.Layout = new PatternLayout("%property{" + Utils.PROPERTY_KEY + "}");
+
+ ILoggerRepository rep = LogManager.CreateRepository(Guid.NewGuid().ToString());
+ BasicConfigurator.Configure(rep, stringAppender);
+
+ ILog log1 = LogManager.GetLogger(rep.Name, "TestThreadStackPattern");
+
+ log1.Info("TestMessage");
+ Assert.AreEqual(SystemInfo.NullText, stringAppender.GetString(), "Test no logical thread stack value set");
+ stringAppender.Reset();
+
+ using (LogicalThreadContext.Stacks[Utils.PROPERTY_KEY].Push("val1"))
+ {
+ log1.Info("TestMessage");
+ Assert.AreEqual("val1", stringAppender.GetString(), "Test logical thread stack value set");
+ stringAppender.Reset();
+
+ using (LogicalThreadContext.Stacks[Utils.PROPERTY_KEY].Push("val2"))
+ {
+ log1.Info("TestMessage");
+ Assert.AreEqual("val1 val2", stringAppender.GetString(), "Test logical thread stack value pushed 2nd val");
+ stringAppender.Reset();
+ }
+ }
+
+ log1.Info("TestMessage");
+ Assert.AreEqual(SystemInfo.NullText, stringAppender.GetString(), "Test logical thread stack value removed");
+ stringAppender.Reset();
+ }
+
+ [Test]
+ public void TestLogicalThreadStackPatternNullVal()
+ {
+ StringAppender stringAppender = new StringAppender();
+ stringAppender.Layout = new PatternLayout("%property{" + Utils.PROPERTY_KEY + "}");
+
+ ILoggerRepository rep = LogManager.CreateRepository(Guid.NewGuid().ToString());
+ BasicConfigurator.Configure(rep, stringAppender);
+
+ ILog log1 = LogManager.GetLogger(rep.Name, "TestThreadStackPattern");
+
+ log1.Info("TestMessage");
+ Assert.AreEqual(SystemInfo.NullText, stringAppender.GetString(), "Test no logical thread stack value set");
+ stringAppender.Reset();
+
+ using (LogicalThreadContext.Stacks[Utils.PROPERTY_KEY].Push(null))
+ {
+ log1.Info("TestMessage");
+ Assert.AreEqual(SystemInfo.NullText, stringAppender.GetString(), "Test logical thread stack value set");
+ stringAppender.Reset();
+ }
+
+ log1.Info("TestMessage");
+ Assert.AreEqual(SystemInfo.NullText, stringAppender.GetString(), "Test logical thread stack value removed");
+ stringAppender.Reset();
+ }
+
+ [Test]
+ public void TestLogicalThreadStackPatternNullVal2()
+ {
+ StringAppender stringAppender = new StringAppender();
+ stringAppender.Layout = new PatternLayout("%property{" + Utils.PROPERTY_KEY + "}");
+
+ ILoggerRepository rep = LogManager.CreateRepository(Guid.NewGuid().ToString());
+ BasicConfigurator.Configure(rep, stringAppender);
+
+ ILog log1 = LogManager.GetLogger(rep.Name, "TestThreadStackPattern");
+
+ log1.Info("TestMessage");
+ Assert.AreEqual(SystemInfo.NullText, stringAppender.GetString(), "Test no logical thread stack value set");
+ stringAppender.Reset();
+
+ using (LogicalThreadContext.Stacks[Utils.PROPERTY_KEY].Push("val1"))
+ {
+ log1.Info("TestMessage");
+ Assert.AreEqual("val1", stringAppender.GetString(), "Test logical thread stack value set");
+ stringAppender.Reset();
+
+ using (LogicalThreadContext.Stacks[Utils.PROPERTY_KEY].Push(null))
+ {
+ log1.Info("TestMessage");
+ Assert.AreEqual("val1 ", stringAppender.GetString(), "Test logical thread stack value pushed null");
+ stringAppender.Reset();
+ }
+ }
+
+ log1.Info("TestMessage");
+ Assert.AreEqual(SystemInfo.NullText, stringAppender.GetString(), "Test logical thread stack value removed");
+ stringAppender.Reset();
+ }
+
+ [Test]
+ public async Task TestLogicalThreadStackPatternAsyncAwait()
+ {
+ StringAppender stringAppender = new StringAppender();
+ stringAppender.Layout = new PatternLayout("%property{" + Utils.PROPERTY_KEY + "}");
+
+ ILoggerRepository rep = LogManager.CreateRepository(Guid.NewGuid().ToString());
+ BasicConfigurator.Configure(rep, stringAppender);
+
+ ILog log1 = LogManager.GetLogger(rep.Name, "TestLogicalThreadStackPattern");
+
+ log1.Info("TestMessage");
+ Assert.AreEqual(SystemInfo.NullText, stringAppender.GetString(), "Test no logical thread stack value set");
+ stringAppender.Reset();
+
+ string testValueForCurrentContext = "Outer";
+ string[] strings = null;
+ using (LogicalThreadContext.Stacks[Utils.PROPERTY_KEY].Push(testValueForCurrentContext))
+ {
+ log1.Info("TestMessage");
+ Assert.AreEqual(testValueForCurrentContext, stringAppender.GetString(), "Test logical thread stack value set");
+ stringAppender.Reset();
+
+ strings = await Task.WhenAll(Enumerable.Range(0, 10).Select(x => SomeWorkStack(x.ToString())));
+ }
+
+ // strings should be ["Outer 0 AOuter 0 AOuter 0Outer 0 BOuter 0 B Outer 0", ...]
+ for (int i = 0; i < strings.Length; i++)
+ {
+ Assert.AreEqual(string.Format("{0} {1} A{0} {1} A{0} {1}{0} {1} B{0} {1} B{0} {1}", testValueForCurrentContext, i), strings[i], "Test logical thread properties expected sequence");
+ }
+
+ log1.Info("TestMessage");
+ Assert.AreEqual(SystemInfo.NullText, stringAppender.GetString(), "Test logical thread properties value removed");
+ stringAppender.Reset();
+ }
+
+ static async Task<string> SomeWorkProperties(string propertyName)
+ {
+ StringAppender stringAppender = new StringAppender();
+ stringAppender.Layout = new PatternLayout("%property{" + Utils.PROPERTY_KEY + "}");
+
+ ILoggerRepository rep = LogManager.CreateRepository(Guid.NewGuid().ToString());
+ BasicConfigurator.Configure(rep, stringAppender);
+
+ ILog log = LogManager.GetLogger(rep.Name, "TestLogicalThreadStackPattern");
+ log.Info("TestMessage");
+
+ // set a new one
+ LogicalThreadContext.Properties[Utils.PROPERTY_KEY] = propertyName;
+ log.Info("TestMessage");
+
+ await MoreWorkProperties(log, "A");
+ log.Info("TestMessage");
+ await MoreWorkProperties(log, "B");
+ log.Info("TestMessage");
+ return stringAppender.GetString();
+ }
+
+ static async Task MoreWorkProperties(ILog log, string propertyName)
+ {
+ LogicalThreadContext.Properties[Utils.PROPERTY_KEY] = propertyName;
+ log.Info("TestMessage");
+ await Task.Delay(1);
+ log.Info("TestMessage");
+ }
+
+ static async Task<string> SomeWorkStack(string stackName)
+ {
+ StringAppender stringAppender = new StringAppender();
+ stringAppender.Layout = new PatternLayout("%property{" + Utils.PROPERTY_KEY + "}");
+
+ ILoggerRepository rep = LogManager.CreateRepository(Guid.NewGuid().ToString());
+ BasicConfigurator.Configure(rep, stringAppender);
+
+ ILog log = LogManager.GetLogger(rep.Name, "TestLogicalThreadStackPattern");
+
+ using (LogicalThreadContext.Stacks[Utils.PROPERTY_KEY].Push(stackName))
+ {
+ log.Info("TestMessage");
+ Assert.AreEqual(string.Format("Outer {0}", stackName), stringAppender.GetString(), "Test logical thread stack value set");
+ stringAppender.Reset();
+
+ await MoreWorkStack(log, "A");
+ log.Info("TestMessage");
+ await MoreWorkStack(log, "B");
+ log.Info("TestMessage");
+ }
+
+ return stringAppender.GetString();
+ }
+
+ static async Task MoreWorkStack(ILog log, string stackName)
+ {
+ using (LogicalThreadContext.Stacks[Utils.PROPERTY_KEY].Push(stackName))
+ {
+ log.Info("TestMessage");
+ await Task.Delay(1);
+ log.Info("TestMessage");
+ }
+ }
+ }
+#endif
+}
\ No newline at end of file
diff --git a/tests/src/Layout/XmlLayoutTest.cs b/tests/src/Layout/XmlLayoutTest.cs
index 9e016b8..1ce0704 100644
--- a/tests/src/Layout/XmlLayoutTest.cs
+++ b/tests/src/Layout/XmlLayoutTest.cs
@@ -81,7 +81,7 @@ private LoggingEventData CreateBaseEvent()
private static string CreateEventNode(string message)
{
return String.Format("<event logger=\"TestLogger\" timestamp=\"{0}\" level=\"INFO\" thread=\"TestThread\" domain=\"Tests\" identity=\"TestRunner\" username=\"TestRunner\"><message>{1}</message></event>" + Environment.NewLine,
-#if NET_2_0 || MONO_2_0
+#if !NETCF
XmlConvert.ToString(DateTime.Today, XmlDateTimeSerializationMode.Local),
#else
XmlConvert.ToString(DateTime.Today),
@@ -92,7 +92,7 @@ private static string CreateEventNode(string message)
private static string CreateEventNode(string key, string value)
{
return String.Format("<event logger=\"TestLogger\" timestamp=\"{0}\" level=\"INFO\" thread=\"TestThread\" domain=\"Tests\" identity=\"TestRunner\" username=\"TestRunner\"><message>Test message</message><properties><data name=\"{1}\" value=\"{2}\" /></properties></event>" + Environment.NewLine,
-#if NET_2_0 || MONO_2_0
+#if !NETCF
XmlConvert.ToString(DateTime.Today, XmlDateTimeSerializationMode.Local),
#else
XmlConvert.ToString(DateTime.Today),
diff --git a/tests/src/Utils.cs b/tests/src/Utils.cs
index 8de9a9f..4e98283 100644
--- a/tests/src/Utils.cs
+++ b/tests/src/Utils.cs
@@ -105,6 +105,7 @@ private static Type[] GetTypesArray(object[] args)
internal static void RemovePropertyFromAllContexts() {
GlobalContext.Properties.Remove(PROPERTY_KEY);
ThreadContext.Properties.Remove(PROPERTY_KEY);
+ LogicalThreadContext.Properties.Remove(PROPERTY_KEY);
}
}
}
\ No newline at end of file
diff --git a/tests/src/log4net.Tests.vs2010.csproj b/tests/src/log4net.Tests.vs2010.csproj
index 13c69a6..72903e8 100644
--- a/tests/src/log4net.Tests.vs2010.csproj
+++ b/tests/src/log4net.Tests.vs2010.csproj
@@ -47,7 +47,7 @@
<UpgradeBackupLocation>
</UpgradeBackupLocation>
<OldToolsVersion>3.5</OldToolsVersion>
- <TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
+ <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
<PublishUrl>publish\</PublishUrl>
<Install>true</Install>
<InstallFrom>Disk</InstallFrom>
@@ -163,6 +165,9 @@
<Compile Include="AssemblyInfo.cs">
<SubType>Code</SubType>
</Compile>
+ <Compile Include="Context\LogicalThreadContextTest.cs">
+ <SubType>Code</SubType>
+ </Compile>
<Compile Include="Context\ThreadContextTest.cs">
<SubType>Code</SubType>
</Compile>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment