commit readying to merge back into trunk

This commit is contained in:
sbohlen
2010-12-02 18:50:33 +00:00
parent f886ca4fc7
commit d1c29bdcdf
7 changed files with 363 additions and 129 deletions

View File

@@ -10,64 +10,78 @@ using Spring.Util;
namespace Spring.Context.Attributes
{
public interface IAssemblyObjectDefinitionScanner
public interface IAssemblyTypeScanner
{
IAssemblyObjectDefinitionScanner AssemblyHavingType<T>();
IAssemblyObjectDefinitionScanner WithAssemblyFilter(Predicate<Assembly> assemblyPredicate);
IAssemblyTypeScanner AssemblyHavingType<T>();
IAssemblyTypeScanner WithAssemblyFilter(Predicate<Assembly> assemblyPredicate);
IAssemblyObjectDefinitionScanner WithIncludeFilter(Predicate<Type> predicate);
IAssemblyObjectDefinitionScanner WithExcludeFilter(Predicate<Type> predicate);
IAssemblyTypeScanner WithIncludeFilter(Predicate<Type> predicate);
IAssemblyTypeScanner WithExcludeFilter(Predicate<Type> predicate);
IAssemblyObjectDefinitionScanner IncludeTypes(IEnumerable<Type> typeSource);
IAssemblyObjectDefinitionScanner IncludeType<T>();
IAssemblyTypeScanner IncludeTypes(IEnumerable<Type> typeSource);
IAssemblyTypeScanner IncludeType<T>();
IAssemblyTypeScanner ExcludeType<T>();
IEnumerable<Type> Scan();
}
public class AssemblyObjectDefinitionScanner : IAssemblyObjectDefinitionScanner
public abstract class AssemblyTypeScanner : IAssemblyTypeScanner
{
private readonly List<Predicate<Assembly>> _assemblyPredicates = new List<Predicate<Assembly>>();
protected readonly List<Predicate<Assembly>> _assemblyPredicates = new List<Predicate<Assembly>>();
private readonly List<Predicate<Type>> _excludePredicates = new List<Predicate<Type>>();
protected readonly List<Predicate<Type>> _excludePredicates = new List<Predicate<Type>>();
private string _folderScanPath;
protected string _folderScanPath;
private readonly List<Predicate<Type>> _includePredicates = new List<Predicate<Type>>();
protected readonly List<Predicate<Type>> _includePredicates = new List<Predicate<Type>>();
private static ILog _logger = LogManager.GetLogger(typeof(AssemblyObjectDefinitionScanner));
protected static ILog _logger = LogManager.GetLogger(typeof(AssemblyTypeScanner));
private readonly List<IEnumerable<Type>> _typeSources = new List<IEnumerable<Type>>();
protected readonly List<IEnumerable<Type>> _typeSources = new List<IEnumerable<Type>>();
/// <summary>
/// Initializes a new instance of the AssemblyObjectDefinitionScanner class.
/// Initializes a new instance of the AssemblyTypeScanner class.
/// </summary>
public AssemblyObjectDefinitionScanner()
/// <param name="folderScanPath"></param>
public AssemblyTypeScanner(string folderScanPath)
{
_folderScanPath = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
if (!string.IsNullOrEmpty(folderScanPath))
{
_folderScanPath = folderScanPath;
}
else
{
_folderScanPath = GetCurrentBinDirectoryPath();
}
}
/// <summary>
/// Initializes a new instance of the AssemblyObjectDefinitionScanner class.
/// Initializes a new instance of the AssemblyTypeScanner class.
/// </summary>
/// <param name="folderScanPath">The folder scan path.</param>
public AssemblyObjectDefinitionScanner(string folderScanPath)
public AssemblyTypeScanner()
{
_folderScanPath = folderScanPath;
}
public IAssemblyObjectDefinitionScanner AssemblyHavingType<T>()
public IAssemblyTypeScanner AssemblyHavingType<T>()
{
_typeSources.Add(new AssemblyTypeSource((typeof(T).Assembly)));
return this;
}
public IAssemblyObjectDefinitionScanner IncludeType<T>()
public IAssemblyTypeScanner ExcludeType<T>()
{
_excludePredicates.Add(t => t == typeof(T));
return this;
}
public IAssemblyTypeScanner IncludeType<T>()
{
_includePredicates.Add(t => t == typeof(T));
return this;
}
public IAssemblyObjectDefinitionScanner IncludeTypes(IEnumerable<Type> typeSource)
public IAssemblyTypeScanner IncludeTypes(IEnumerable<Type> typeSource)
{
AssertUtils.ArgumentNotNull(typeSource, "typeSource");
_typeSources.Add(typeSource);
@@ -75,9 +89,9 @@ namespace Spring.Context.Attributes
return this;
}
public IEnumerable<Type> Scan()
public virtual IEnumerable<Type> Scan()
{
SetDefaultFiltersIfNeeded();
SetDefaultFilters();
IList<Type> types = new List<Type>();
@@ -90,7 +104,7 @@ namespace Spring.Context.Attributes
{
foreach (Type type in typeSource)
{
if (IsIncludedType(type) && !IsExcludedType(type) && HasComponentAttribute(type))
if (IsIncludedType(type) && !IsExcludedType(type) && FinalVetoConstraintIsSatisfiedBy(type))
{
types.Add(type);
}
@@ -100,19 +114,19 @@ namespace Spring.Context.Attributes
return types;
}
public IAssemblyObjectDefinitionScanner WithAssemblyFilter(Predicate<Assembly> assemblyPredicate)
public IAssemblyTypeScanner WithAssemblyFilter(Predicate<Assembly> assemblyPredicate)
{
_assemblyPredicates.Add(assemblyPredicate);
return this;
}
public IAssemblyObjectDefinitionScanner WithExcludeFilter(Predicate<Type> predicate)
public IAssemblyTypeScanner WithExcludeFilter(Predicate<Type> predicate)
{
_excludePredicates.Add(predicate);
return this;
}
public IAssemblyObjectDefinitionScanner WithIncludeFilter(Predicate<Type> predicate)
public IAssemblyTypeScanner WithIncludeFilter(Predicate<Type> predicate)
{
_includePredicates.Add(predicate);
return this;
@@ -130,6 +144,18 @@ namespace Spring.Context.Attributes
return false;
}
protected virtual bool IsIncludedAssembly(Assembly assembly)
{
foreach (var include in _assemblyPredicates)
{
if (include(assembly))
{
return true;
}
}
return false;
}
protected virtual bool IsIncludedType(Type type)
{
foreach (var include in _includePredicates)
@@ -142,67 +168,90 @@ namespace Spring.Context.Attributes
return false;
}
private bool HasComponentAttribute(Type type)
protected virtual void SetDefaultFilters()
{
return Attribute.GetCustomAttribute(type, typeof(ConfigurationAttribute), true) != null;
if (_includePredicates.Count == 0)
_includePredicates.Add(t => true);
if (_excludePredicates.Count == 0)
_excludePredicates.Add(t => false);
if (_assemblyPredicates.Count == 0)
_assemblyPredicates.Add(a => true);
}
private IEnumerable<Assembly> GetAllMatchingAssemblies()
protected virtual bool FinalVetoConstraintIsSatisfiedBy(Type type)
{
IList<Assembly> assemblyCandidates = new List<Assembly>();
return true;
}
IEnumerable<string> files = Directory.GetFiles(_folderScanPath, "*.dll");
private IEnumerable<Assembly> ApplyAssemblyFiltersTo(IEnumerable<Assembly> assemblyCandidates)
{
IList<Assembly> matchingAssemblies = new List<Assembly>();
foreach (Assembly assemblyCandidate in assemblyCandidates)
if (IsIncludedAssembly(assemblyCandidate))
matchingAssemblies.Add(assemblyCandidate);
return matchingAssemblies;
}
private IEnumerable<Assembly> GetAllAssembliesInPath(string folderPath)
{
IList<Assembly> assemblies = new List<Assembly>();
IEnumerable<string> files = Directory.GetFiles(folderPath, "*.dll");
foreach (string file in files)
{
try
{
assemblyCandidates.Add(Assembly.LoadFrom(file));
assemblies.Add(Assembly.LoadFrom(file));
}
catch (Exception ex)
{
//log and swallow everything that might go wrong here...
if (_logger.IsDebugEnabled)
_logger.Debug("Failed to load type while scanning Assemblies for Defintions!", ex);
}
}
IList<Assembly> assemblies = new List<Assembly>();
foreach (Assembly assemblyCandidate in assemblyCandidates)
{
foreach (var include in _assemblyPredicates)
{
if (include(assemblyCandidate))
{
assemblies.Add(assemblyCandidate);
break;
}
}
}
return assemblies;
}
private void SetDefaultFiltersIfNeeded()
private IEnumerable<Assembly> GetAllMatchingAssemblies()
{
if (_includePredicates.Count == 0)
{
_includePredicates.Add(t => true);
}
IEnumerable<Assembly> assemblyCandidates = GetAllAssembliesInPath(_folderScanPath);
return ApplyAssemblyFiltersTo(assemblyCandidates);
}
if (_excludePredicates.Count == 0)
{
_excludePredicates.Add(t => false);
}
private string GetCurrentBinDirectoryPath()
{
return Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
}
if (_assemblyPredicates.Count == 0)
{
_assemblyPredicates.Add(a => true);
}
}
public class AssemblyObjectDefinitionScanner : AssemblyTypeScanner
{
/// <summary>
/// Initializes a new instance of the AssemblyObjectDefinitionScanner class.
/// </summary>
/// <param name="folderScanPath">The folder scan path.</param>
public AssemblyObjectDefinitionScanner(string folderScanPath)
: base(folderScanPath)
{ }
/// <summary>
/// Initializes a new instance of the AssemblyObjectDefinitionScanner class.
/// </summary>
public AssemblyObjectDefinitionScanner()
: base(null)
{ }
//protected override bool RequiredConstraintIsSatisfiedBy(Type type)
//{
// return Attribute.GetCustomAttribute(type, typeof(ConfigurationAttribute), true) != null;
//}
protected override void SetDefaultFilters()
{
_includePredicates.Add(t => Attribute.GetCustomAttribute(t, typeof(ConfigurationAttribute), true) != null);
base.SetDefaultFilters();
}
}

View File

@@ -11,7 +11,7 @@ namespace Spring.Objects.Factory.Support
{
public static class AssemblyScanningExtensionMethods
{
public static void Scan(this IObjectDefinitionRegistry registry, IAssemblyObjectDefinitionScanner scanner)
public static void Scan(this IObjectDefinitionRegistry registry, IAssemblyTypeScanner scanner)
{
IEnumerable<Type> configTypes = scanner.Scan();
@@ -21,27 +21,23 @@ namespace Spring.Objects.Factory.Support
EnsureConfigurationClassPostProcessorIsRegisteredFor(registry);
}
RegisiterDefintionsForConfigTypes(configTypes, registry);
RegisiterDefintionsForTypes(configTypes, registry);
}
public static void Scan(this IObjectDefinitionRegistry registry)
{
Scan(registry, new AssemblyObjectDefinitionScanner());
}
public static void Scan(this IObjectDefinitionRegistry registry, Predicate<Type> typePredicate)
{
Scan(registry, string.Empty, ta => true, typePredicate);
Scan(registry, null, ta => true, typePredicate);
}
public static void Scan(this IObjectDefinitionRegistry registry, string assemblyScanPath, Predicate<Assembly> assemblyPredicate, Predicate<Type> typePredicate)
{
IAssemblyObjectDefinitionScanner scanner;
//create a scanner instance using the scan path (or not!) as appropropriate
if (string.IsNullOrEmpty(assemblyScanPath))
{
scanner = new AssemblyObjectDefinitionScanner();
}
else
{
scanner = new AssemblyObjectDefinitionScanner(assemblyScanPath);
}
//create a scanner instance using the scan path
IAssemblyTypeScanner scanner = new AssemblyObjectDefinitionScanner(assemblyScanPath);
//configure the scanner per the provided constraints
scanner.WithAssemblyFilter(assemblyPredicate).WithIncludeFilter(typePredicate);
@@ -50,19 +46,14 @@ namespace Spring.Objects.Factory.Support
Scan(registry, scanner);
}
public static void Scan(this IObjectDefinitionRegistry registry, Predicate<Assembly> assemblyPredicate)
{
Scan(registry, string.Empty, assemblyPredicate, t => true);
}
public static void Scan(this IObjectDefinitionRegistry registry, Predicate<Assembly> assemblyPredicate, Predicate<Type> typePredicate)
{
Scan(registry, string.Empty, assemblyPredicate, typePredicate);
Scan(registry, null, assemblyPredicate, typePredicate);
}
public static void Scan(this IObjectDefinitionRegistry registry)
public static void Scan(this IObjectDefinitionRegistry registry, Predicate<Assembly> assemblyPredicate)
{
Scan(registry, new AssemblyObjectDefinitionScanner());
Scan(registry, null, assemblyPredicate, t => true);
}
/// <summary>
@@ -79,15 +70,15 @@ namespace Spring.Objects.Factory.Support
}
/// <summary>
/// Regisiters the defintions for config types.
/// Regisiters the defintions for types.
/// </summary>
/// <param name="configTypes">The config types.</param>
/// <param name="typesToRegister">The types to register.</param>
/// <param name="registry">The registry.</param>
private static void RegisiterDefintionsForConfigTypes(IEnumerable<Type> configTypes, IObjectDefinitionRegistry registry)
private static void RegisiterDefintionsForTypes(IEnumerable<Type> typesToRegister, IObjectDefinitionRegistry registry)
{
foreach (Type configType in configTypes)
foreach (Type type in typesToRegister)
{
ObjectDefinitionBuilder definition = ObjectDefinitionBuilder.GenericObjectDefinition(configType);
ObjectDefinitionBuilder definition = ObjectDefinitionBuilder.GenericObjectDefinition(type);
registry.RegisterObjectDefinition(definition.ObjectDefinition.ObjectTypeName, definition.ObjectDefinition);
}
}

View File

@@ -1417,6 +1417,65 @@ namespace Spring.Util
MemberwiseCopyInternal(fromObject, toObject, smallerType);
}
/// <summary>
/// Convenience method that uses reflection to return the value of a non-public field of a given object.
/// </summary>
/// <remarks>Useful in certain instances during testing to avoid the need to add protected properties, etc. to a class just to facilitate testing.</remarks>
/// <param name="obj">The instance of the object from which to retrieve the field value.</param>
/// <param name="fieldName">Name of the field on the object from which to retrieve the value.</param>
/// <returns></returns>
public static object GetInstanceFieldValue(object obj, string fieldName)
{
if (obj == null)
throw new ArgumentNullException("obj", "obj is null.");
if (String.IsNullOrEmpty(fieldName))
throw new ArgumentException("fieldName is null or empty.", "fieldName");
FieldInfo f = obj.GetType().GetField(fieldName, BindingFlags.SetField | BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public);
if (f != null)
return f.GetValue(obj);
else
{
throw new ArgumentException(string.Format("Non-public instance field '{0}' could not be found in class of type '{1}'", fieldName, obj.GetType().ToString()));
}
}
/// <summary>
/// Convenience method that uses reflection to set the value of a non-public field of a given object.
/// </summary>
/// <remarks>Useful in certain instances during testing to avoid the need to add protected properties, etc. to a class just to facilitate testing.</remarks>
/// <param name="obj">The instance of the object from which to set the field value.</param>
/// <param name="fieldName">Name of the field on the object to which to set the value.</param>
/// <param name="fieldValue">The field value to set.</param>
public static void SetInstanceFieldValue(object obj, string fieldName, object fieldValue)
{
if (obj == null)
throw new ArgumentNullException("obj", "obj is null.");
if (String.IsNullOrEmpty(fieldName))
throw new ArgumentException("fieldName is null or empty.", "fieldName");
if (fieldValue == null)
throw new ArgumentNullException("fieldValue", "fieldValue is null.");
FieldInfo f = obj.GetType().GetField(fieldName, BindingFlags.SetField | BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public);
if (f != null)
{
if (f.FieldType != fieldValue.GetType())
throw new ArgumentException(string.Format("fieldValue for fieldName '{0}' of object type '{1}' must be of type '{2}' but was of type '{3}'", fieldName, obj.GetType().ToString(), f.FieldType.ToString(), fieldValue.GetType().ToString()), "fieldValue");
f.SetValue(obj, fieldValue);
}
else
{
throw new ArgumentException(string.Format("Non-public instance field '{0}' could not be found in class of type '{1}'", fieldName, obj.GetType().ToString()));
}
}
#if NET_2_0
private static void MemberwiseCopyInternal(object fromObject, object toObject, Type smallerType)
{

View File

@@ -0,0 +1,101 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using NUnit.Framework;
using Spring.Util;
namespace Spring.Context.Attributes
{
[TestFixture]
public class AssemblyTypeScannerTests
{
private class Scanner : AssemblyTypeScanner
{
public Scanner(string folderScanPath)
: base(folderScanPath)
{ }
public Scanner()
: base(null)
{ }
}
private Scanner _scanner;
private List<Predicate<Type>> _excludePredicates
{
get
{
//get at the collection of excludePredicates from the private field
//(yuck!-- test smell, but at least its wrapped up in a neat private property getter!)
return (List<Predicate<Type>>)(ReflectionUtils.GetInstanceFieldValue(_scanner, "_excludePredicates"));
}
}
private List<Predicate<Type>> _includePredicates
{
get
{
//get at the collection of includePredicates from the private field
//(yuck!-- test smell, but at least its wrapped up in a neat private property getter!)
return (List<Predicate<Type>>)(ReflectionUtils.GetInstanceFieldValue(_scanner, "_includePredicates"));
}
}
private List<IEnumerable<Type>> _typeSources
{
get
{
//get at the collection of typeSources from the private field
//(yuck!-- test smell, but at least its wrapped up in a neat private property getter!)
return (List<IEnumerable<Type>>)(ReflectionUtils.GetInstanceFieldValue(_scanner, "_typeSources"));
}
}
[SetUp]
public void _TestSetup()
{
_scanner = new Scanner();
}
[Test]
public void AssemblyHavingType_T_Adds_Assembly()
{
_scanner.AssemblyHavingType<Spring.Core.IOrdered>();
Assert.That(_typeSources.Any(t => t.Contains(typeof(Spring.Core.IOrdered))));
}
[Test]
public void IncludeType_T_Adds_Type()
{
_scanner.IncludeType<Spring.Core.IOrdered>();
_scanner.IncludeType<Spring.Core.IPriorityOrdered>();
_includePredicates.Any(p => p(typeof(Spring.Core.IOrdered)));
_includePredicates.Any(p => p(typeof(Spring.Core.IPriorityOrdered)));
}
[Test]
public void WithExcludeFilter_Excludes_Type()
{
_scanner.IncludeType<TheConfigurationClass>();
_scanner.IncludeType<TheImportedConfigurationClass>();
_scanner.WithExcludeFilter(t => t.Name.StartsWith("TheImported"));
Assert.That(_scanner.Scan(), Contains.Item((typeof(TheConfigurationClass))));
Assert.False(_scanner.Scan().Contains(typeof(TheImportedConfigurationClass)));
}
[Test]
public void WithIncludeFilter_Includes_Types()
{
_scanner.WithIncludeFilter(t => t.Name.Contains("ConfigurationClass"));
Assert.That(_scanner.Scan(), Contains.Item((typeof(TheConfigurationClass))));
Assert.That(_scanner.Scan(), Contains.Item((typeof(TheImportedConfigurationClass))));
}
}
}

View File

@@ -34,7 +34,7 @@ namespace Spring.Context.Attributes
try
{
attrib.DefinitionReader = typeof(Assert);// <--need to use *anything* ensured *not* to implement IObjectDefinitionReader
attrib.DefinitionReader = typeof(Object);// <--need to use *anything* ensured *not* to implement IObjectDefinitionReader
Assert.Fail("Expected Exception of type ArgumentException not thrown!");
}
catch (ArgumentException)

View File

@@ -14,52 +14,85 @@ namespace Spring.Objects.Factory.Support
[TestFixture]
public class AssemblyScanningExtensionMethodsTests
{
[Test]
public void Integration_Scenario_With_Assembly_Filtering()
private GenericApplicationContext _context;
[SetUp]
public void _TestSetup()
{
GenericApplicationContext context = new GenericApplicationContext();
context.Scan(a => a.GetName().Name.StartsWith("Spring.Core.Configuration."));
context.Refresh();
AssertExpectedObjectsAreRegisteredWith(context);
}
[Test]
//TODO: double check to ensure that this test really SHOULD pass...seems like its finding too wide a collection of assy's to scan... :(
public void Integration_Scenario_With_Assembly_Filtering_Containing_Specific_Type()
{
GenericApplicationContext context = new GenericApplicationContext();
context.Scan(assy => assy.GetTypes().Any(type => type.FullName.Contains(typeof(MarkerTypeForScannerToFind).Name)));
context.Refresh();
AssertExpectedObjectsAreRegisteredWith(context);
_context = new GenericApplicationContext();
}
[Test]
public void Integration_Scenario_With_Type_Filtering()
public void Can_Filter_For_Assembly_Based_On_Assembly_Metadata()
{
GenericApplicationContext context = new GenericApplicationContext();
context.Scan(type => ((Type)type).FullName.Contains(typeof(TheConfigurationClass).Name));
context.Refresh();
_context.Scan(a => a.GetName().Name.StartsWith("Spring.Core.Configuration."));
_context.Refresh();
AssertExpectedObjectsAreRegisteredWith(context);
AssertExpectedObjectsAreRegisteredWith(_context);
}
[Test]
public void Integration_Scenario_With_Default_of_No_Filtering()
public void Can_Filter_For_Assembly_Containing_Specific_Type_But_Having_NO_Definitions()
{
GenericApplicationContext context = new GenericApplicationContext();
context.Scan();
context.Refresh();
//specifically filter assemblies for one that we *know* will result in NO [Configuration] types in it
_context.Scan(assy => assy.GetTypes().Any(type => type.FullName.Contains(typeof(Spring.Core.IOrdered).Name)));
_context.Refresh();
AssertExpectedObjectsAreRegisteredWith(context);
Assert.That(_context.DefaultListableObjectFactory.ObjectDefinitionCount, Is.EqualTo(0));
}
private void AssertExpectedObjectsAreRegisteredWith(GenericApplicationContext context)
[Test]
public void Can_Filter_For_Assembly_Containing_Specific_Type()
{
Assert.That(context.DefaultListableObjectFactory.ObjectDefinitionCount, Is.EqualTo(13));
_context.Scan(assy => assy.GetTypes().Any(type => type.FullName.Contains(typeof(MarkerTypeForScannerToFind).Name)));
_context.Refresh();
AssertExpectedObjectsAreRegisteredWith(_context);
}
[Test]
public void Can_Filter_For_Specific_Type()
{
_context.Scan(type => ((Type)type).FullName.Contains(typeof(TheImportedConfigurationClass).Name));
_context.Refresh();
Assert.That(_context.DefaultListableObjectFactory.ObjectDefinitionCount, Is.EqualTo(4));
}
[Test]
public void Can_Filter_For_Specific_Types_With_Compound_Predicate()
{
_context.Scan(type => ((Type)type).FullName.Contains(typeof(TheImportedConfigurationClass).Name) || ((Type)type).FullName.Contains(typeof(TheConfigurationClass).Name));
_context.Refresh();
AssertExpectedObjectsAreRegisteredWith(_context);
}
[Test]
public void Can_Filter_For_Specific_Types_With_Multiple_Include_Filters()
{
var scanner = new AssemblyObjectDefinitionScanner();
scanner.WithIncludeFilter(type => ((Type)type).FullName.Contains(typeof(TheImportedConfigurationClass).Name));
scanner.WithIncludeFilter(type => ((Type)type).FullName.Contains(typeof(TheConfigurationClass).Name));
_context.Scan(scanner);
_context.Refresh();
AssertExpectedObjectsAreRegisteredWith(_context);
}
[Test]
public void Can_Perform_Scan_With_No_Filtering()
{
_context.Scan();
_context.Refresh();
AssertExpectedObjectsAreRegisteredWith(_context);
}
private void AssertExpectedObjectsAreRegisteredWith(GenericApplicationContext _context)
{
Assert.That(_context.DefaultListableObjectFactory.ObjectDefinitionCount, Is.EqualTo(13));
}
}

View File

@@ -40,6 +40,7 @@
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="Context\Attributes\AssemblyTypeScannerTests.cs" />
<Compile Include="Context\Attributes\ConfigurationClassPostProcessorTests.cs" />
<Compile Include="Context\Attributes\DefinitionAttributeTests.cs" />
<Compile Include="Context\Attributes\ImportResourceAttributeTests.cs" />