Initial attempt at fleshing out the scanning extension method API; further review and comment/discussion needed

This commit is contained in:
sbohlen
2010-11-20 19:19:01 +00:00
parent 85af8a1d8f
commit 962e571ef5
10 changed files with 505 additions and 5 deletions

View File

@@ -0,0 +1,43 @@
using System;
using System.Collections.Generic;
using System.Text;
using Spring.Objects.Factory.Xml;
using Spring.Objects.Factory.Support;
using Spring.Util;
using Spring.Context.Attributes;
using Spring.Objects.Factory.Config;
namespace Spring.Context.Config
{
public class AttributeConfigObjectDefinitionParser : IObjectDefinitionParser
{
/// <summary>
/// The object name of the internally managed configuration attribure processor
/// </summary>
public static readonly string CONFIGURATION_ATTRIBUTE_PROCESSOR_OBJECT_NAME = "Spring.Context.Attributes.InternalConfigurationAttributeProcessor";
private static readonly Type ConfigurationClassPostProcessorType = typeof(ConfigurationClassPostProcessor);
public AttributeConfigObjectDefinitionParser()
{
}
public Objects.Factory.Config.IObjectDefinition ParseElement(System.Xml.XmlElement element, ParserContext parserContext)
{
IObjectDefinitionRegistry registry = parserContext.ReaderContext.Registry;
AssertUtils.ArgumentNotNull(registry, "registry");
if (!registry.ContainsObjectDefinition(CONFIGURATION_ATTRIBUTE_PROCESSOR_OBJECT_NAME))
{
RootObjectDefinition objectDefinition = new RootObjectDefinition(ConfigurationClassPostProcessorType);
objectDefinition.Role = ObjectRole.ROLE_INFRASTRUCTURE;
registry.RegisterObjectDefinition(CONFIGURATION_ATTRIBUTE_PROCESSOR_OBJECT_NAME, objectDefinition);
}
return null;
}
}
}

View File

@@ -0,0 +1,15 @@
using System;
using System.Collections.Generic;
using System.Text;
using Spring.Objects.Factory.Xml;
namespace Spring.Context.Config
{
public class ComponentScanObjectDefinitionParser
{
public ComponentScanObjectDefinitionParser()
{
}
}
}

View File

@@ -0,0 +1,79 @@
<?xml version="1.0" encoding="UTF-8"?>
<xsd:schema xmlns="http://www.springframework.net/context"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:objects="http://www.springframework.net"
xmlns:tool="http://www.springframework.net/tool"
targetNamespace="http://www.springframework.net/context"
elementFormDefault="qualified"
attributeFormDefault="unqualified">
<xsd:import namespace="http://www.springframework.net"/>
<xsd:import namespace="http://www.springframework.net/tool"/>
<xsd:annotation>
<xsd:documentation><![CDATA[
Defines the configuration elements for the Spring Framework's application
context support. Effects the activation of various configuration styles
for the containing Spring ApplicationContext.
]]></xsd:documentation>
</xsd:annotation>
<xsd:element name="attribute-config">
<xsd:annotation>
<xsd:documentation><![CDATA[
Activates various annotations to be detected in bean classes: Spring's @Required and
@Autowired, as well as JSR 250's @PostConstruct, @PreDestroy and @Resource (if available),
JAX-WS's @WebServiceRef (if available), EJB3's @EJB (if available), and JPA's
@PersistenceContext and @PersistenceUnit (if available). Alternatively, you may
choose to activate the individual BeanPostProcessors for those annotations.
Note: This tag does not activate processing of Spring's @Transactional or EJB3's
@TransactionAttribute annotation. Consider the use of the <tx:annotation-driven>
tag for that purpose.
]]></xsd:documentation>
</xsd:annotation>
</xsd:element>
<xsd:element name="component-scan">
<xsd:annotation>
<xsd:documentation><![CDATA[
Scans the classpath for annotated components that will be auto-registered as
Spring beans. By default, the Spring-provided @Component, @Repository,
@Service, and @Controller stereotypes will be detected.
Note: This tag implies the effects of the 'annotation-config' tag, activating @Required,
@Autowired, @PostConstruct, @PreDestroy, @Resource, @PersistenceContext and @PersistenceUnit
annotations in the component classes, which is usually desired for autodetected components
(without external configuration). Turn off the 'annotation-config' attribute to deactivate
this default behavior, for example in order to use custom BeanPostProcessor definitions
for handling those annotations.
Note: You may use placeholders in package paths, but only resolved against system
properties (analogous to resource paths). A component scan results in new bean definition
being registered; Spring's PropertyPlaceholderConfigurer will apply to those bean
definitions just like to regular bean definitions, but it won't apply to the component
scan settings themselves.
]]></xsd:documentation>
</xsd:annotation>
<xsd:complexType>
<xsd:attribute name="attribute-config" type="xsd:boolean"
default="true">
<xsd:annotation>
<xsd:documentation><![CDATA[
Indicates whether the implicit annotation post-processors should be enabled. Default is "true".
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="name-generator" type="xsd:string">
<xsd:annotation>
<xsd:documentation><![CDATA[
The fully-qualified class name of the BeanNameGenerator to be used for naming detected components.
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
</xsd:complexType>
</xsd:element>
</xsd:schema>

View File

@@ -0,0 +1,150 @@
using System;
using System.Collections.Generic;
using System.Text;
using System.Reflection;
using System.Linq;
using System.IO;
using Common.Logging;
using Spring.Context.Attributes;
namespace Spring.Objects.Factory.Support
{
public static class AssemblyScanningExtensionMethods
{
private static ILog _logger = LogManager.GetLogger(typeof(AssemblyScanningExtensionMethods));
/// <summary>
/// Scans the assemblies for definitions.
/// </summary>
/// <param name="registry">The registry.</param>
/// <param name="assemblyScanPath">The assembly scan path.</param>
/// <param name="assemblyFilenamePredicate">The assembly filename predicate.</param>
/// <param name="assemblyMetadataPredicate">The assembly metadata predicate.</param>
/// <returns></returns>
public static void ScanAssembliesAndRegisterDefinitions(this IObjectDefinitionRegistry registry, string assemblyScanPath, Func<string, bool> assemblyFilenamePredicate, Func<Assembly, bool> assemblyMetadataPredicate)
{
IEnumerable<Assembly> assemblies = GetAllMatchingAssemblies(assemblyScanPath, assemblyFilenamePredicate);
assemblies = assemblies.Where(assembly => assemblyMetadataPredicate(assembly));
IEnumerable<Type> configTypes = GetAllConfigurationTypesDefinedIn(assemblies);
//if we have at least one config class, ensure the post-processor is registered
if (configTypes.Count() > 0)
{
EnsureConfigurationClassPostProcessorIsRegisteredFor(registry);
}
RegisiterDefintionsForConfigTypes(configTypes, registry);
}
/// <summary>
/// Scans the assemblies for definitions.
/// </summary>
/// <param name="registry">The registry.</param>
/// <param name="assemblyMetadataPredicate">The assembly metadata predicate.</param>
/// <returns></returns>
public static void ScanAssembliesAndRegisterDefinitions(this IObjectDefinitionRegistry registry, Func<Assembly, bool> assemblyMetadataPredicate)
{
ScanAssembliesAndRegisterDefinitions(registry, Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), fn => true, assemblyMetadataPredicate);
}
/// <summary>
/// Scans the assemblies for definitions.
/// </summary>
/// <param name="registry">The registry.</param>
/// <param name="assemblyFilenamePredicate">The assembly filename predicate.</param>
/// <param name="assemblyMetadataPredicate">The assembly metadata predicate.</param>
/// <returns></returns>
public static void ScanAssembliesAndRegisterDefinitions(this IObjectDefinitionRegistry registry, Func<string, bool> assemblyFilenamePredicate, Func<Assembly, bool> assemblyMetadataPredicate)
{
ScanAssembliesAndRegisterDefinitions(registry, Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), assemblyFilenamePredicate, assemblyMetadataPredicate);
}
public static void ScanAssembliesAndRegisterDefinitions(this IObjectDefinitionRegistry registry)
{
ScanAssembliesAndRegisterDefinitions(registry, Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), fn => true, a => true);
}
/// <summary>
/// Ensures the configuration class post processor is registered for.
/// </summary>
/// <param name="registry">The registry.</param>
private static void EnsureConfigurationClassPostProcessorIsRegisteredFor(IObjectDefinitionRegistry registry)
{
var postProcessorBuilder = ObjectDefinitionBuilder.GenericObjectDefinition(typeof(ConfigurationClassPostProcessor));
if (!registry.ContainsObjectDefinition(postProcessorBuilder.ObjectDefinition.ObjectTypeName))
{
registry.RegisterObjectDefinition(postProcessorBuilder.ObjectDefinition.ObjectTypeName, postProcessorBuilder.ObjectDefinition);
}
}
/// <summary>
/// Gets all configuration types defined in the assemblies.
/// </summary>
/// <param name="assemblies">The assemblies.</param>
/// <returns></returns>
private static IEnumerable<Type> GetAllConfigurationTypesDefinedIn(IEnumerable<Assembly> assemblies)
{
IList<Type> types = new List<Type>();
foreach (Assembly assembly in assemblies)
{
foreach (Type type in assembly.GetTypes())
{
if (Attribute.GetCustomAttribute(type, typeof(ConfigurationAttribute), true) != null)
{
types.Add(type);
}
}
}
return types;
}
/// <summary>
/// Gets all matching assemblies.
/// </summary>
/// <param name="assemblyScanPath">The assembly scan path.</param>
/// <param name="assemblyFilenamePredicate">The assembly filename predicate.</param>
/// <returns></returns>
private static IEnumerable<Assembly> GetAllMatchingAssemblies(string assemblyScanPath, Func<string, bool> assemblyFilenamePredicate)
{
IList<Assembly> assemblies = new List<Assembly>();
IEnumerable<string> files = Directory.GetFiles(assemblyScanPath, "*.dll").Where(s => assemblyFilenamePredicate(Path.GetFileName(s)));
foreach (string file in files)
{
try
{
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);
}
}
return assemblies;
}
/// <summary>
/// Regisiters the defintions for config types.
/// </summary>
/// <param name="configTypes">The config types.</param>
/// <param name="registry">The registry.</param>
private static void RegisiterDefintionsForConfigTypes(IEnumerable<Type> configTypes, IObjectDefinitionRegistry registry)
{
foreach (Type configType in configTypes)
{
ObjectDefinitionBuilder definition = ObjectDefinitionBuilder.GenericObjectDefinition(configType);
registry.RegisterObjectDefinition(definition.ObjectDefinition.ObjectTypeName, definition.ObjectDefinition);
}
}
}
}

View File

@@ -10,8 +10,9 @@
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>Spring</RootNamespace>
<AssemblyName>Spring.Core.Configuration</AssemblyName>
<TargetFrameworkVersion>v2.0</TargetFrameworkVersion>
<TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<TargetFrameworkProfile />
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
@@ -56,6 +57,7 @@
<Compile Include="Context\Config\AttributeConfigObjectDefinitionParser.cs" />
<Compile Include="Context\Config\ComponentScanObjectDefinitionParser.cs" />
<Compile Include="Context\Config\ContextNamespaceParser.cs" />
<Compile Include="Objects\Factory\Support\AssemblyScanningExtensionMethods.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
<ItemGroup>

View File

@@ -0,0 +1,153 @@
<?xml version="1.0" encoding="utf-8"?>
<ClassDiagram MajorVersion="1" MinorVersion="1">
<Class Name="Spring.Context.Support.AbstractApplicationContext" Collapsed="true">
<Position X="2.75" Y="8.75" Width="2" />
<TypeIdentifier>
<HashCode>SHQRYAEIiGBAtMBASYTEWAQkWBAiChEMaAACCAFBXMg=</HashCode>
<FileName>Context\Support\AbstractApplicationContext.cs</FileName>
</TypeIdentifier>
<Lollipop Position="0.2" />
</Class>
<Class Name="Spring.Context.Support.AbstractXmlApplicationContext" Collapsed="true">
<Position X="1" Y="10.25" Width="2.25" />
<TypeIdentifier>
<HashCode>AAQACAAAAABAAACBAAQAAQAAABAAAAAAABAAAAACAEA=</HashCode>
<FileName>Context\Support\AbstractXmlApplicationContext.cs</FileName>
</TypeIdentifier>
</Class>
<Class Name="Spring.Context.Support.GenericApplicationContext" Collapsed="true">
<Position X="4" Y="10.25" Width="2.25" />
<TypeIdentifier>
<HashCode>AAQAAAAAAAAAAAAAAAQAAAAAABAAIAAAAAAAAAAEAAA=</HashCode>
<FileName>Context\Support\GenericApplicationContext.cs</FileName>
</TypeIdentifier>
</Class>
<Class Name="Spring.Context.Support.XmlApplicationContext" Collapsed="true">
<Position X="1.25" Y="11.75" Width="2" />
<TypeIdentifier>
<HashCode>AAAACAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAIAEAAA=</HashCode>
<FileName>Context\Support\XmlApplicationContext.cs</FileName>
</TypeIdentifier>
</Class>
<Class Name="Spring.Context.Support.StaticApplicationContext" Collapsed="true">
<Position X="4.25" Y="11.75" Width="2" />
<TypeIdentifier>
<HashCode>AAEAAAAAAAAAAAAIAAQAAAAAAgAAAAAAAAAAAAAAAAA=</HashCode>
<FileName>Context\Support\StaticApplicationContext.cs</FileName>
</TypeIdentifier>
</Class>
<Class Name="Spring.Core.IO.ConfigurableResourceLoader" Collapsed="true">
<Position X="2.5" Y="7.5" Width="2.25" />
<TypeIdentifier>
<HashCode>AAAAAAAAAAAAggAAAQAAAAAABAAAAAAAAAAASAAAAAA=</HashCode>
<FileName>Core\IO\ConfigurableResourceLoader.cs</FileName>
</TypeIdentifier>
<Lollipop Position="0.2" />
</Class>
<Interface Name="Spring.Context.IConfigurableApplicationContext" Collapsed="true">
<Position X="9.5" Y="5.5" Width="2.5" />
<TypeIdentifier>
<HashCode>AAQAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAACEA=</HashCode>
<FileName>Context\IConfigurableApplicationContext.cs</FileName>
</TypeIdentifier>
</Interface>
<Interface Name="Spring.Context.IApplicationContext" Collapsed="true">
<Position X="10" Y="3.5" Width="1.75" />
<TypeIdentifier>
<HashCode>AAAAAAAAAAAAEAAAAACAAAQAAAAAAAAAAAAAAAAACAA=</HashCode>
<FileName>Context\IApplicationContext.cs</FileName>
</TypeIdentifier>
</Interface>
<Interface Name="Spring.Context.ILifecycle" Collapsed="true">
<Position X="13" Y="4.25" Width="1.5" />
<TypeIdentifier>
<HashCode>AAAAAAAAACAAAAAAAAAAQAAAAAAAAAAAIAAAAAAAAAA=</HashCode>
<FileName>Context\ILifecycle.cs</FileName>
</TypeIdentifier>
</Interface>
<Interface Name="Spring.Objects.Factory.IObjectFactory" Collapsed="true">
<Position X="6.5" Y="0.5" Width="1.5" />
<TypeIdentifier>
<HashCode>ABAAAAAAAAAAIIAACIAACAAAAAAAAgEMAAAAAAAAAIA=</HashCode>
<FileName>Objects\Factory\IObjectFactory.cs</FileName>
</TypeIdentifier>
</Interface>
<Interface Name="Spring.Objects.Factory.Config.IAutowireCapableObjectFactory" Collapsed="true">
<Position X="3.25" Y="2" Width="2.5" />
<TypeIdentifier>
<HashCode>AAAAAAAAAAAAAACAAAAAAAAIAAQAAAAgEAAAAAAAAAA=</HashCode>
<FileName>Objects\Factory\Config\IAutowireCapableObjectFactory.cs</FileName>
</TypeIdentifier>
</Interface>
<Interface Name="Spring.Objects.Factory.IHierarchicalObjectFactory" Collapsed="true">
<Position X="6.5" Y="2" Width="2" />
<TypeIdentifier>
<HashCode>AAAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAQAA=</HashCode>
<FileName>Objects\Factory\IHierarchicalObjectFactory.cs</FileName>
</TypeIdentifier>
</Interface>
<Interface Name="Spring.Objects.Factory.IListableObjectFactory" Collapsed="true">
<Position X="9.25" Y="2" Width="1.75" />
<TypeIdentifier>
<HashCode>CAAAAAAAAAAAAAAAQABAEAAAAAAAAAAACAAAAAAAAAA=</HashCode>
<FileName>Objects\Factory\IListableObjectFactory.cs</FileName>
</TypeIdentifier>
</Interface>
<Interface Name="Spring.Objects.Factory.Config.IConfigurableListableObjectFactory" Collapsed="true">
<Position X="5.75" Y="3.5" Width="2.75" />
<TypeIdentifier>
<HashCode>AAAAAAAAAAAAAIAAAIAEAAAgAAAAAAAAAAAACABAAAA=</HashCode>
<FileName>Objects\Factory\Config\IConfigurableListableObjectFactory.cs</FileName>
</TypeIdentifier>
</Interface>
<Interface Name="Spring.Objects.Factory.Config.IConfigurableObjectFactory" Collapsed="true">
<Position X="6.5" Y="5.5" Width="2.25" />
<TypeIdentifier>
<HashCode>AAAAAAAABCAAAAAAAAACAAAAQAAEAAAAAAAAAQAAEAA=</HashCode>
<FileName>Objects\Factory\Config\IConfigurableObjectFactory.cs</FileName>
</TypeIdentifier>
</Interface>
<Interface Name="Spring.Objects.Factory.Config.ISingletonObjectRegistry" Collapsed="true">
<Position X="2.5" Y="4" Width="2" />
<TypeIdentifier>
<HashCode>AAAAAAAAEAAAABAIAAAAAAAAAAAAAAAAAAAAAgAAAIA=</HashCode>
<FileName>Objects\Factory\Config\ISingletonObjectRegistry.cs</FileName>
</TypeIdentifier>
</Interface>
<Interface Name="Spring.Context.IMessageSource" Collapsed="true">
<Position X="12.25" Y="2" Width="1.5" />
<TypeIdentifier>
<HashCode>ACAAAAAAAAAAAAAAAAAAAAAACAAAABAAAAAAAAAAAAA=</HashCode>
<FileName>Context\IMessageSource.cs</FileName>
</TypeIdentifier>
</Interface>
<Interface Name="Spring.Context.IApplicationEventPublisher" Collapsed="true">
<Position X="14.5" Y="2" Width="2.25" />
<TypeIdentifier>
<HashCode>AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAA=</HashCode>
<FileName>Context\IApplicationEventPublisher.cs</FileName>
</TypeIdentifier>
</Interface>
<Interface Name="Spring.Core.IO.IResourceLoader" Collapsed="true">
<Position X="17.5" Y="2" Width="1.5" />
<TypeIdentifier>
<HashCode>AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAAAAAA=</HashCode>
<FileName>Core\IO\IResourceLoader.cs</FileName>
</TypeIdentifier>
</Interface>
<Interface Name="Spring.Objects.Events.IEventRegistry" Collapsed="true">
<Position X="19.75" Y="2" Width="1.5" />
<TypeIdentifier>
<HashCode>AAAAAAAAAAAAAAAAAAAAAAAAAAACAAAAQAAAAAAAAIA=</HashCode>
<FileName>Objects\Events\IEventRegistry.cs</FileName>
</TypeIdentifier>
</Interface>
<Interface Name="Spring.Objects.Factory.Support.IObjectDefinitionRegistry">
<Position X="0.5" Y="0.75" Width="2.25" />
<TypeIdentifier>
<HashCode>CBAAAAAAAAAAAAAAQAAEEAAgABAAAAAAAAAAAAAAEAA=</HashCode>
<FileName>Objects\Factory\Support\IObjectDefinitionRegistry.cs</FileName>
</TypeIdentifier>
</Interface>
<Font Name="Segoe UI" Size="9" />
</ClassDiagram>

View File

@@ -1218,6 +1218,7 @@
<Compile Include="Validation\Validators\UrlValidator.cs">
<SubType>Code</SubType>
</Compile>
<None Include="ContextClassDiagram.cd" />
<None Include="Expressions\Expression.g" />
<EmbeddedResource Include="Objects\Factory\Xml\spring-tool-1.1.xsd">
<SubType>

View File

@@ -18,11 +18,11 @@ namespace Spring.Context.Attributes
{
_ctx = new GenericApplicationContext();
var builder = ObjectDefinitionBuilder.GenericObjectDefinition(typeof(TheConfigurationClass));
_ctx.RegisterObjectDefinition("theConfigClass", builder.ObjectDefinition);
var configDefinitionBuilder = ObjectDefinitionBuilder.GenericObjectDefinition(typeof(TheConfigurationClass));
_ctx.RegisterObjectDefinition(configDefinitionBuilder.ObjectDefinition.ObjectTypeName, configDefinitionBuilder.ObjectDefinition);
var b2 = ObjectDefinitionBuilder.GenericObjectDefinition(typeof(ConfigurationClassPostProcessor));
_ctx.RegisterObjectDefinition("thePostProcessor", b2.ObjectDefinition);
var postProcessorDefintionBuilder = ObjectDefinitionBuilder.GenericObjectDefinition(typeof(ConfigurationClassPostProcessor));
_ctx.RegisterObjectDefinition(postProcessorDefintionBuilder.ObjectDefinition.ObjectTypeName, postProcessorDefintionBuilder.ObjectDefinition);
Assert.That(_ctx.ObjectDefinitionCount, Is.EqualTo(2));

View File

@@ -0,0 +1,56 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using NUnit.Framework;
using System.Reflection;
using System.Diagnostics;
using Spring.Context.Config;
using Spring.Context.Support;
namespace Spring.Objects.Factory.Support
{
[TestFixture]
public class AssemblyScanningExtensionMethodsTests
{
[Test]
public void Integration_Scenario_With_Defaults()
{
GenericApplicationContext context = new GenericApplicationContext();
context.ScanAssembliesAndRegisterDefinitions();// (assy => assy.GetTypes().Any(type => type.FullName.Contains("SomeType")));
context.Refresh();
AssertExpectedObjectsAreRegisteredWith(context);
}
[Test]
public void Integration_Scenario_With_Filtering_Example()
{
GenericApplicationContext context = new GenericApplicationContext();
context.ScanAssembliesAndRegisterDefinitions(assy => assy.GetTypes().Any(type => type.FullName.Contains(typeof(MarkerTypeForScannerToFind).Name)));
context.Refresh();
AssertExpectedObjectsAreRegisteredWith(context);
}
private static void AssertExpectedObjectsAreRegisteredWith(GenericApplicationContext context)
{
Assert.That(context.DefaultListableObjectFactory.ObjectDefinitionCount, Is.EqualTo(13));
}
[Test]
public void Integration_Scenario_With_Complex_Filtering_Example()
{
GenericApplicationContext context = new GenericApplicationContext();
context.ScanAssembliesAndRegisterDefinitions(fn => fn.StartsWith("Spring."), assy => assy.GetTypes().Any(type => type.FullName.Contains(typeof(MarkerTypeForScannerToFind).Name)));
context.Refresh();
AssertExpectedObjectsAreRegisteredWith(context);
}
}
public class MarkerTypeForScannerToFind
{
}
}

View File

@@ -44,6 +44,7 @@
<Compile Include="Context\Attributes\DefinitionAttributeTests.cs" />
<Compile Include="Context\Attributes\ImportResourceAttributeTests.cs" />
<Compile Include="Context\Config\ContextNamespaceParserTests.cs" />
<Compile Include="Objects\Factory\Support\AssemblyScanningExtensionMethodsTests.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
<ItemGroup>