diff --git a/src/ZeroLog.Tests.ExternalAppender/TestAppender.cs b/src/ZeroLog.Tests.ExternalAppender/TestAppender.cs
new file mode 100644
index 00000000..aba5c722
--- /dev/null
+++ b/src/ZeroLog.Tests.ExternalAppender/TestAppender.cs
@@ -0,0 +1,24 @@
+using JetBrains.Annotations;
+using ZeroLog.Appenders;
+
+namespace ZeroLog.Tests.ExternalAppender
+{
+ [UsedImplicitly]
+ public class TestAppender : ConsoleAppender
+ {
+ public TestAppender()
+ {
+ }
+
+ public TestAppender(string prefixPattern)
+ : base(prefixPattern)
+ {
+ }
+
+ public override void Configure(DefaultAppenderConfig parameters)
+ {
+ parameters.PrefixPattern = $"({Name}): {parameters.PrefixPattern}";
+ base.Configure(parameters);
+ }
+ }
+}
diff --git a/src/ZeroLog.Tests.ExternalAppender/ZeroLog.Tests.ExternalAppender.csproj b/src/ZeroLog.Tests.ExternalAppender/ZeroLog.Tests.ExternalAppender.csproj
new file mode 100644
index 00000000..6540ad3d
--- /dev/null
+++ b/src/ZeroLog.Tests.ExternalAppender/ZeroLog.Tests.ExternalAppender.csproj
@@ -0,0 +1,10 @@
+
+
+ netstandard2.0
+
+
+
+
+
+
+
diff --git a/src/ZeroLog.Tests/Appenders/ExternalAppenderTest.cs b/src/ZeroLog.Tests/Appenders/ExternalAppenderTest.cs
new file mode 100644
index 00000000..62b50f6a
--- /dev/null
+++ b/src/ZeroLog.Tests/Appenders/ExternalAppenderTest.cs
@@ -0,0 +1,43 @@
+using System.Linq;
+using NUnit.Framework;
+using ZeroLog.Appenders;
+using ZeroLog.Config;
+using ZeroLog.ConfigResolvers;
+
+namespace ZeroLog.Tests.Appenders
+{
+ [TestFixture]
+ public class ExternalAppenderTest
+ {
+ [Test]
+ public void should_resolve_appender_from_assembly_qualified_name()
+ {
+ var appenderDef = new AppenderDefinition
+ {
+ Name = "ExtApp1",
+ AppenderTypeName = "ZeroLog.Tests.ExternalAppender.TestAppender, ZeroLog.Tests.ExternalAppender",
+ AppenderJsonConfig = new DefaultAppenderConfig { PrefixPattern = "[%level] @ %time - %logger: " }
+ };
+
+ var config = new ZeroLogJsonConfiguration
+ {
+ LogEventBufferSize = 5,
+ LogEventQueueSize = 7,
+ RootLogger = new LoggerDefinition
+ {
+ Level = Level.Info,
+ LogEventPoolExhaustionStrategy = LogEventPoolExhaustionStrategy.DropLogMessage,
+ AppenderReferences = new[] { "ExtApp1" },
+ },
+ Appenders = new[] { appenderDef },
+ };
+
+ var configResolver = new HierarchicalResolver();
+ configResolver.Build(config);
+
+ var appenders = configResolver.GetAllAppenders().ToList();
+ Assert.AreEqual(1, appenders.Count);
+ Assert.AreEqual("ZeroLog.Tests.ExternalAppender.TestAppender", ((GuardedAppender)appenders[0]).Appender.GetType().FullName);
+ }
+ }
+}
diff --git a/src/ZeroLog.Tests/ZeroLog.Tests.csproj b/src/ZeroLog.Tests/ZeroLog.Tests.csproj
index 48efb490..e5843c40 100644
--- a/src/ZeroLog.Tests/ZeroLog.Tests.csproj
+++ b/src/ZeroLog.Tests/ZeroLog.Tests.csproj
@@ -7,6 +7,7 @@
+
diff --git a/src/ZeroLog.sln b/src/ZeroLog.sln
index 47f7c3f1..bca02441 100644
--- a/src/ZeroLog.sln
+++ b/src/ZeroLog.sln
@@ -6,6 +6,9 @@ MinimumVisualStudioVersion = 10.0.40219.1
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ZeroLog", "ZeroLog\ZeroLog.csproj", "{34665A87-497B-4C4E-928E-1DFBEB3F7441}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ZeroLog.Tests", "ZeroLog.Tests\ZeroLog.Tests.csproj", "{F2405E3E-69ED-4BA5-A862-CF920B612B16}"
+ ProjectSection(ProjectDependencies) = postProject
+ {B40F81DD-A04A-4E50-8063-5023DB1E7975} = {B40F81DD-A04A-4E50-8063-5023DB1E7975}
+ EndProjectSection
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Misc", "Misc", "{44EDCA3A-DBC5-415C-9A34-C742912674B5}"
ProjectSection(SolutionItems) = preProject
@@ -19,6 +22,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Misc", "Misc", "{44EDCA3A-D
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ZeroLog.Benchmarks", "ZeroLog.Benchmarks\ZeroLog.Benchmarks.csproj", "{D8CB63CF-F35E-4D38-88AF-9FB4C6B29630}"
EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ZeroLog.Tests.ExternalAppender", "ZeroLog.Tests.ExternalAppender\ZeroLog.Tests.ExternalAppender.csproj", "{B40F81DD-A04A-4E50-8063-5023DB1E7975}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -37,6 +42,10 @@ Global
{D8CB63CF-F35E-4D38-88AF-9FB4C6B29630}.Debug|Any CPU.Build.0 = Debug|Any CPU
{D8CB63CF-F35E-4D38-88AF-9FB4C6B29630}.Release|Any CPU.ActiveCfg = Release|Any CPU
{D8CB63CF-F35E-4D38-88AF-9FB4C6B29630}.Release|Any CPU.Build.0 = Release|Any CPU
+ {B40F81DD-A04A-4E50-8063-5023DB1E7975}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {B40F81DD-A04A-4E50-8063-5023DB1E7975}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {B40F81DD-A04A-4E50-8063-5023DB1E7975}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {B40F81DD-A04A-4E50-8063-5023DB1E7975}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
diff --git a/src/ZeroLog/Appenders/AppenderFactory.cs b/src/ZeroLog/Appenders/AppenderFactory.cs
index bc0953bb..cc3b1b8b 100644
--- a/src/ZeroLog/Appenders/AppenderFactory.cs
+++ b/src/ZeroLog/Appenders/AppenderFactory.cs
@@ -28,11 +28,13 @@ public static IAppender CreateAppender(AppenderDefinition definition)
private static Type GetAppenderType(AppenderDefinition definition)
{
- var appenderType = AppDomain.CurrentDomain.GetAssemblies()
- .Select(x => x.GetType(definition.AppenderTypeName))
- .FirstOrDefault(x => x != null);
+ // Check if we have an assembly-qualified name of a type
+ if (definition.AppenderTypeName.Contains(","))
+ return Type.GetType(definition.AppenderTypeName, true, false);
- return appenderType;
+ return AppDomain.CurrentDomain.GetAssemblies()
+ .Select(x => x.GetType(definition.AppenderTypeName))
+ .FirstOrDefault(x => x != null);
}
private static object GetAppenderParameters(AppenderDefinition definition, Type appenderParameterType)
diff --git a/src/ZeroLog/Appenders/GuardedAppender.cs b/src/ZeroLog/Appenders/GuardedAppender.cs
index 55d1db66..b3a516ae 100644
--- a/src/ZeroLog/Appenders/GuardedAppender.cs
+++ b/src/ZeroLog/Appenders/GuardedAppender.cs
@@ -6,21 +6,22 @@ namespace ZeroLog.Appenders
{
internal class GuardedAppender : IAppender
{
- private readonly IAppender _appender;
private readonly TimeSpan _quarantineDelay;
private DateTime? _nextActivationTime;
+ internal IAppender Appender { get; }
+
public GuardedAppender(IAppender appender, TimeSpan quarantineDelay)
{
- _appender = appender;
+ Appender = appender;
_quarantineDelay = quarantineDelay;
_nextActivationTime = null;
}
public string Name
{
- get => _appender.Name;
- set => _appender.Name = value;
+ get => Appender.Name;
+ set => Appender.Name = value;
}
public void WriteEvent(ILogEventHeader logEventHeader, byte[] messageBytes, int messageLength)
@@ -30,7 +31,7 @@ public void WriteEvent(ILogEventHeader logEventHeader, byte[] messageBytes, int
try
{
- _appender.WriteEvent(logEventHeader, messageBytes, messageLength);
+ Appender.WriteEvent(logEventHeader, messageBytes, messageLength);
_nextActivationTime = null;
}
catch (Exception)
@@ -40,12 +41,12 @@ public void WriteEvent(ILogEventHeader logEventHeader, byte[] messageBytes, int
}
public void SetEncoding(Encoding encoding)
- => _appender.SetEncoding(encoding);
+ => Appender.SetEncoding(encoding);
public void Flush()
- => _appender.Flush();
+ => Appender.Flush();
public void Dispose()
- => _appender.Dispose();
+ => Appender.Dispose();
}
}