Permalink
Browse files

Added additional indirection to ConfigurationItemFactory to enable pl…

…ugging in DI containers.
  • Loading branch information...
jkowalski committed Jul 10, 2011
1 parent 3fd0ef5 commit f55672b241da9e65a1bfef995085bd2aa46a1b79
@@ -0,0 +1,52 @@
+//
+// Copyright (c) 2004-2011 Jaroslaw Kowalski <jaak@jkowalski.net>
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+// this list of conditions and the following disclaimer.
+//
+// * Redistributions in binary form must reproduce the above copyright notice,
+// this list of conditions and the following disclaimer in the documentation
+// and/or other materials provided with the distribution.
+//
+// * Neither the name of Jaroslaw Kowalski nor the names of its
+// contributors may be used to endorse or promote products derived from this
+// software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+// THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+namespace NLog.Config
+{
+ using System;
+ using System.Collections.Generic;
+ using System.Reflection;
+ using NLog.Conditions;
+ using NLog.Filters;
+ using NLog.Internal;
+ using NLog.LayoutRenderers;
+ using NLog.Layouts;
+ using NLog.Targets;
+
+ /// <summary>
+ /// Constructs a new instance the configuration item (target, layout, layout renderer, etc.) given its type.
+ /// </summary>
+ /// <param name="itemType">Type of the item.</param>
+ /// <returns>Created object of the specified type.</returns>
+ public delegate object ConfigurationItemCreator(Type itemType);
+}
@@ -38,6 +38,7 @@ namespace NLog.Config
using System.Reflection;
using NLog.Conditions;
using NLog.Filters;
+ using NLog.Internal;
using NLog.LayoutRenderers;
using NLog.Layouts;
using NLog.Targets;
@@ -48,12 +49,12 @@ namespace NLog.Config
public class ConfigurationItemFactory
{
private readonly IList<object> allFactories;
- private readonly Factory<Target, TargetAttribute> targets = new Factory<Target, TargetAttribute>();
- private readonly Factory<Filter, FilterAttribute> filters = new Factory<Filter, FilterAttribute>();
- private readonly Factory<LayoutRenderer, LayoutRendererAttribute> layoutRenderers = new Factory<LayoutRenderer, LayoutRendererAttribute>();
- private readonly Factory<Layout, LayoutAttribute> layouts = new Factory<Layout, LayoutAttribute>();
- private readonly MethodFactory<ConditionMethodsAttribute, ConditionMethodAttribute> conditionMethods = new MethodFactory<ConditionMethodsAttribute, ConditionMethodAttribute>();
- private readonly Factory<LayoutRenderer, AmbientPropertyAttribute> ambientProperties = new Factory<LayoutRenderer, AmbientPropertyAttribute>();
+ private readonly Factory<Target, TargetAttribute> targets;
+ private readonly Factory<Filter, FilterAttribute> filters;
+ private readonly Factory<LayoutRenderer, LayoutRendererAttribute> layoutRenderers;
+ private readonly Factory<Layout, LayoutAttribute> layouts;
+ private readonly MethodFactory<ConditionMethodsAttribute, ConditionMethodAttribute> conditionMethods;
+ private readonly Factory<LayoutRenderer, AmbientPropertyAttribute> ambientProperties;
/// <summary>
/// Initializes static members of the <see cref="ConfigurationItemFactory"/> class.
@@ -69,6 +70,13 @@ static ConfigurationItemFactory()
/// <param name="assemblies">The assemblies to scan for named items.</param>
public ConfigurationItemFactory(params Assembly[] assemblies)
{
+ this.CreateInstance = FactoryHelper.CreateInstance;
+ this.targets = new Factory<Target, TargetAttribute>(this);
+ this.filters = new Factory<Filter, FilterAttribute>(this);
+ this.layoutRenderers = new Factory<LayoutRenderer, LayoutRendererAttribute>(this);
+ this.layouts = new Factory<Layout, LayoutAttribute>(this);
+ this.conditionMethods = new MethodFactory<ConditionMethodsAttribute, ConditionMethodAttribute>();
+ this.ambientProperties = new Factory<LayoutRenderer, AmbientPropertyAttribute>(this);
this.allFactories = new List<object>
{
this.targets,
@@ -90,6 +98,14 @@ public ConfigurationItemFactory(params Assembly[] assemblies)
/// </summary>
public static ConfigurationItemFactory Default { get; set; }
+ /// <summary>
+ /// Gets or sets the creator delegate used to instantiate configuration objects.
+ /// </summary>
+ /// <remarks>
+ /// By overriding this property, one can enable dependency injection or interception for created objects.
+ /// </remarks>
+ public ConfigurationItemCreator CreateInstance { get; set; }
+
/// <summary>
/// Gets the <see cref="Target"/> factory.
/// </summary>
@@ -49,6 +49,12 @@ internal class Factory<TBaseType, TAttributeType> : INamedItemFactory<TBaseType,
where TAttributeType : NameBaseAttribute
{
private readonly Dictionary<string, GetTypeDelegate> items = new Dictionary<string, GetTypeDelegate>(StringComparer.OrdinalIgnoreCase);
+ private ConfigurationItemFactory parentFactory;
+
+ internal Factory(ConfigurationItemFactory parentFactory)
+ {
+ this.parentFactory = parentFactory;
+ }
private delegate Type GetTypeDelegate();
@@ -173,7 +179,7 @@ public bool TryCreateInstance(string itemName, out TBaseType result)
return false;
}
- result = (TBaseType)Activator.CreateInstance(type);
+ result = (TBaseType)this.parentFactory.CreateInstance(type);
return true;
}
View
@@ -701,7 +701,6 @@ private Logger GetLogger(LoggerCacheKey cacheKey)
}
}
- // Activator.CreateInstance(cacheKey.ConcreteType);
Logger newLogger;
if (cacheKey.ConcreteType != null && cacheKey.ConcreteType != typeof(Logger))
View
@@ -96,6 +96,7 @@
<Compile Include="Config\AppDomainFixedOutputAttribute.cs" />
<Compile Include="Config\ArrayParameterAttribute.cs" />
<Compile Include="Config\ConfigSectionHandler.cs" />
+ <Compile Include="Config\ConfigurationItemCreator.cs" />
<Compile Include="Config\ConfigurationItemFactory.cs" />
<Compile Include="Config\DefaultParameterAttribute.cs" />
<Compile Include="Config\Factory.cs" />
@@ -96,6 +96,7 @@
<Compile Include="Config\AppDomainFixedOutputAttribute.cs" />
<Compile Include="Config\ArrayParameterAttribute.cs" />
<Compile Include="Config\ConfigSectionHandler.cs" />
+ <Compile Include="Config\ConfigurationItemCreator.cs" />
<Compile Include="Config\ConfigurationItemFactory.cs" />
<Compile Include="Config\DefaultParameterAttribute.cs" />
<Compile Include="Config\Factory.cs" />
@@ -374,4 +375,4 @@
<Compile Include="$(BuildInfoFile)" />
</ItemGroup>
</Target>
-</Project>
+</Project>
@@ -98,6 +98,7 @@
<Compile Include="Config\AppDomainFixedOutputAttribute.cs" />
<Compile Include="Config\ArrayParameterAttribute.cs" />
<Compile Include="Config\ConfigSectionHandler.cs" />
+ <Compile Include="Config\ConfigurationItemCreator.cs" />
<Compile Include="Config\ConfigurationItemFactory.cs" />
<Compile Include="Config\DefaultParameterAttribute.cs" />
<Compile Include="Config\Factory.cs" />
@@ -102,6 +102,7 @@
<Compile Include="Config\AppDomainFixedOutputAttribute.cs" />
<Compile Include="Config\ArrayParameterAttribute.cs" />
<Compile Include="Config\ConfigSectionHandler.cs" />
+ <Compile Include="Config\ConfigurationItemCreator.cs" />
<Compile Include="Config\ConfigurationItemFactory.cs" />
<Compile Include="Config\DefaultParameterAttribute.cs" />
<Compile Include="Config\Factory.cs" />
@@ -387,4 +388,4 @@
<Compile Include="$(BuildInfoFile)" />
</ItemGroup>
</Target>
-</Project>
+</Project>
@@ -21,8 +21,7 @@
<DeployDirSuffix>NLog</DeployDirSuffix>
<NativePlatformName>Pocket PC 2003</NativePlatformName>
<TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
- <FormFactorID>
- </FormFactorID>
+ <FormFactorID></FormFactorID>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
@@ -104,6 +103,7 @@
<Compile Include="Config\AppDomainFixedOutputAttribute.cs" />
<Compile Include="Config\ArrayParameterAttribute.cs" />
<Compile Include="Config\ConfigSectionHandler.cs" />
+ <Compile Include="Config\ConfigurationItemCreator.cs" />
<Compile Include="Config\ConfigurationItemFactory.cs" />
<Compile Include="Config\DefaultParameterAttribute.cs" />
<Compile Include="Config\Factory.cs" />
@@ -389,4 +389,4 @@
<Compile Include="$(BuildInfoFile)" />
</ItemGroup>
</Target>
-</Project>
+</Project>
@@ -92,6 +92,7 @@
<Compile Include="Config\AppDomainFixedOutputAttribute.cs" />
<Compile Include="Config\ArrayParameterAttribute.cs" />
<Compile Include="Config\ConfigSectionHandler.cs" />
+ <Compile Include="Config\ConfigurationItemCreator.cs" />
<Compile Include="Config\ConfigurationItemFactory.cs" />
<Compile Include="Config\DefaultParameterAttribute.cs" />
<Compile Include="Config\Factory.cs" />
@@ -371,4 +372,4 @@
<Compile Include="$(BuildInfoFile)" />
</ItemGroup>
</Target>
-</Project>
+</Project>
@@ -94,6 +94,7 @@
<Compile Include="Config\AppDomainFixedOutputAttribute.cs" />
<Compile Include="Config\ArrayParameterAttribute.cs" />
<Compile Include="Config\ConfigSectionHandler.cs" />
+ <Compile Include="Config\ConfigurationItemCreator.cs" />
<Compile Include="Config\ConfigurationItemFactory.cs" />
<Compile Include="Config\DefaultParameterAttribute.cs" />
<Compile Include="Config\Factory.cs" />
@@ -373,4 +374,4 @@
<Compile Include="$(BuildInfoFile)" />
</ItemGroup>
</Target>
-</Project>
+</Project>
@@ -98,6 +98,7 @@
<Compile Include="Config\AppDomainFixedOutputAttribute.cs" />
<Compile Include="Config\ArrayParameterAttribute.cs" />
<Compile Include="Config\ConfigSectionHandler.cs" />
+ <Compile Include="Config\ConfigurationItemCreator.cs" />
<Compile Include="Config\ConfigurationItemFactory.cs" />
<Compile Include="Config\DefaultParameterAttribute.cs" />
<Compile Include="Config\Factory.cs" />
@@ -377,4 +378,4 @@
<Compile Include="$(BuildInfoFile)" />
</ItemGroup>
</Target>
-</Project>
+</Project>
View
@@ -96,6 +96,7 @@
<Compile Include="Config\AppDomainFixedOutputAttribute.cs" />
<Compile Include="Config\ArrayParameterAttribute.cs" />
<Compile Include="Config\ConfigSectionHandler.cs" />
+ <Compile Include="Config\ConfigurationItemCreator.cs" />
<Compile Include="Config\ConfigurationItemFactory.cs" />
<Compile Include="Config\DefaultParameterAttribute.cs" />
<Compile Include="Config\Factory.cs" />
@@ -379,4 +380,4 @@
<Compile Include="$(BuildInfoFile)" />
</ItemGroup>
</Target>
-</Project>
+</Project>
View
@@ -96,6 +96,7 @@
<Compile Include="Config\AppDomainFixedOutputAttribute.cs" />
<Compile Include="Config\ArrayParameterAttribute.cs" />
<Compile Include="Config\ConfigSectionHandler.cs" />
+ <Compile Include="Config\ConfigurationItemCreator.cs" />
<Compile Include="Config\ConfigurationItemFactory.cs" />
<Compile Include="Config\DefaultParameterAttribute.cs" />
<Compile Include="Config\Factory.cs" />
@@ -379,4 +380,4 @@
<Compile Include="$(BuildInfoFile)" />
</ItemGroup>
</Target>
-</Project>
+</Project>
View
@@ -97,6 +97,7 @@
<Compile Include="Config\AppDomainFixedOutputAttribute.cs" />
<Compile Include="Config\ArrayParameterAttribute.cs" />
<Compile Include="Config\ConfigSectionHandler.cs" />
+ <Compile Include="Config\ConfigurationItemCreator.cs" />
<Compile Include="Config\ConfigurationItemFactory.cs" />
<Compile Include="Config\DefaultParameterAttribute.cs" />
<Compile Include="Config\Factory.cs" />
@@ -380,4 +381,4 @@
<Compile Include="$(BuildInfoFile)" />
</ItemGroup>
</Target>
-</Project>
+</Project>
View
@@ -99,6 +99,7 @@
<Compile Include="Config\AppDomainFixedOutputAttribute.cs" />
<Compile Include="Config\ArrayParameterAttribute.cs" />
<Compile Include="Config\ConfigSectionHandler.cs" />
+ <Compile Include="Config\ConfigurationItemCreator.cs" />
<Compile Include="Config\ConfigurationItemFactory.cs" />
<Compile Include="Config\DefaultParameterAttribute.cs" />
<Compile Include="Config\Factory.cs" />
@@ -381,4 +382,4 @@
<Compile Include="$(BuildInfoFile)" />
</ItemGroup>
</Target>
-</Project>
+</Project>
@@ -99,6 +99,7 @@
<Compile Include="Config\AppDomainFixedOutputAttribute.cs" />
<Compile Include="Config\ArrayParameterAttribute.cs" />
<Compile Include="Config\ConfigSectionHandler.cs" />
+ <Compile Include="Config\ConfigurationItemCreator.cs" />
<Compile Include="Config\ConfigurationItemFactory.cs" />
<Compile Include="Config\DefaultParameterAttribute.cs" />
<Compile Include="Config\Factory.cs" />
@@ -381,4 +382,4 @@
<Target Name="AfterBuild">
</Target>
-->
-</Project>
+</Project>
@@ -43,11 +43,42 @@ namespace NLog.UnitTests.Config
using TearDown = Microsoft.VisualStudio.TestTools.UnitTesting.TestCleanupAttribute;
#endif
using NLog.Config;
+ using NLog.Internal;
using NLog.Targets;
+using System.Collections.Generic;
[TestFixture]
public class ConfigurationItemFactoryTests : NLogTestBase
{
+ [Test]
+ public void ConfigurationItemFactoryDefaultTest()
+ {
+ var cif = new ConfigurationItemFactory();
+ Assert.IsInstanceOfType(typeof(DebugTarget), cif.CreateInstance(typeof(DebugTarget)));
+ }
+
+ [Test]
+ public void ConfigurationItemFactorySimpleTest()
+ {
+ var cif = new ConfigurationItemFactory();
+ cif.RegisterType(typeof(DebugTarget), string.Empty);
+ var target = cif.Targets.CreateInstance("Debug") as DebugTarget;
+ Assert.IsNotNull(target);
+ }
+
+ [Test]
+ public void ConfigurationItemFactoryUsesSuppliedDelegateToResolveObject()
+ {
+ var cif = new ConfigurationItemFactory();
+ cif.RegisterType(typeof(DebugTarget), string.Empty);
+ List<Type> resolvedTypes = new List<Type>();
+ cif.CreateInstance = t => { resolvedTypes.Add(t); return FactoryHelper.CreateInstance(t); };
+ Target target = cif.Targets.CreateInstance("Debug");
+ Assert.IsNotNull(target);
+ Assert.AreEqual(1, resolvedTypes.Count);
+ Assert.AreEqual(typeof(DebugTarget), resolvedTypes[0]);
+ }
+
#if !SILVERLIGHT && !NET_CF
// this is just to force reference to NLog.Extended.dll
public Type ForceExtendedReference = typeof(MessageQueueTarget).DeclaringType;

0 comments on commit f55672b

Please sign in to comment.