Skip to content

Commit

Permalink
Support for atom compositions
Browse files Browse the repository at this point in the history
  • Loading branch information
sagifogel committed Jul 4, 2014
1 parent e73f64d commit 531a560
Show file tree
Hide file tree
Showing 13 changed files with 172 additions and 535 deletions.
2 changes: 1 addition & 1 deletion NCop.Composite/Engine/CompositeRegistryDecorator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ public CompositeRegistryDecorator(INCopDependencyAwareRegistry regisrty) {
}

public void Register(Type concreteType, Type serviceType, ITypeMap dependencies, string name = null) {
name = serviceType.GetNameFromAttribute();
name = name ?? serviceType.GetNameFromAttribute();

regisrty.Register(concreteType, serviceType, dependencies, name);
}
Expand Down
2 changes: 1 addition & 1 deletion NCop.Composite/IoC/CompositeContainerAdapter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ public INCopDependencyContainer CreateChildContainer() {

public void Register(Type concreteType, Type serviceType, ITypeMap dependencies = null, string name = null) {
var castAs = serviceType.GetTypeFromAttribute();
var compositeRegistration = new CompositeFrameworkRegistration(container, concreteType, serviceType, dependencies, castAs);
var compositeRegistration = new CompositeFrameworkRegistration(container, concreteType, serviceType, dependencies, castAs, name);

container.Register(compositeRegistration);
}
Expand Down
6 changes: 4 additions & 2 deletions NCop.Composite/IoC/CompositeFrameworkRegistration.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ internal class CompositeFrameworkRegistration : IRegistration
private readonly CompositeRegistration registration = null;
private readonly IRegistrationResolver registrationResolver = null;

internal CompositeFrameworkRegistration(IRegistrationResolver registrationResolver, Type concreteType, Type serviceType, IEnumerable<TypeMap> dependencies = null, Type castTo = null) {
internal CompositeFrameworkRegistration(IRegistrationResolver registrationResolver, Type concreteType, Type serviceType, IEnumerable<TypeMap> dependencies = null, Type castTo = null, string name = null) {
NamedAttribute namedAttribute = null;

this.serviceType = serviceType;
Expand All @@ -37,8 +37,10 @@ internal CompositeFrameworkRegistration(IRegistrationResolver registrationResolv
if (IsSingletonComposite()) {
registration.Scope = ReuseScope.Hierarchy;
}

registration.Name = name;

if (TryGetNamedAttribute(out namedAttribute)) {
if (name.IsNullOrEmpty() && TryGetNamedAttribute(out namedAttribute)) {
registration.Name = namedAttribute.Name;
}

Expand Down
40 changes: 40 additions & 0 deletions NCop.Composite/Mixins/Weaving/AtomCompositeMixinsWeaverBuilder.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
using NCop.Composite.Weaving;
using NCop.Core;
using NCop.IoC;
using NCop.Mixins.Engine;
using NCop.Mixins.Weaving;
using NCop.Weaving;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace NCop.Composite.Mixins.Weaving
{
internal class AtomCompositeMixinsWeaverBuilder : AbstractTypeWeaverBuilder, ICompositeMixinsTypeWeaverBuilder
{
private TypeMap mixin = null;
protected readonly INCopDependencyAwareRegistry registry = null;
private readonly string atomIdentifier = Guid.NewGuid().ToString();

public AtomCompositeMixinsWeaverBuilder(Type type, ITypeDefinition typeDefinition, INCopDependencyAwareRegistry registry)
: base(type, typeDefinition) {
this.registry = registry;
}

public override void AddMethodWeavers() {
base.AddMethodWeavers();
registry.Register(mixin.ImplementationType, mixin.ContractType, name: atomIdentifier);
}

public override ITypeWeaver CreateTypeWeaver() {
return new AtomMixinsWeaverStartegy(typeDefinition, mixin, methodWeavers, registry);
}

public void Add(TypeMap item) {
Interlocked.CompareExchange(ref mixin, item, null);
}
}
}
19 changes: 19 additions & 0 deletions NCop.Composite/Mixins/Weaving/CompositeMixinsWeaverBuilder.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
using NCop.Composite.Weaving;
using NCop.IoC;
using NCop.Mixins.Weaving;
using NCop.Weaving;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace NCop.Composite.Mixins.Weaving
{
internal class CompositeMixinsWeaverBuilder : MixinsTypeWeaverBuilder, ICompositeMixinsTypeWeaverBuilder
{
public CompositeMixinsWeaverBuilder(Type type, ITypeDefinition typeDefinition, INCopDependencyAwareRegistry registry)
: base(type, typeDefinition, registry) {
}
}
}
14 changes: 14 additions & 0 deletions NCop.Composite/Mixins/Weaving/ICompositeMixinsTypeWeaverBuilder.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
using NCop.Mixins.Engine;
using NCop.Weaving;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace NCop.Composite.Weaving
{
public interface ICompositeMixinsTypeWeaverBuilder : ITypeWeaverBuilder, IMethodWeaverBuilderBag, IPropertyWeaverBag, IMixinMapBag
{
}
}
4 changes: 4 additions & 0 deletions NCop.Composite/NCop.Composite.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,8 @@
<Compile Include="Framework\TransientCompositeAttribute.cs" />
<Compile Include="IoC\CompositeContainerAdapter.cs" />
<Compile Include="IoC\CompositeRegistration.cs" />
<Compile Include="Mixins\Weaving\AtomCompositeMixinsWeaverBuilder.cs" />
<Compile Include="Mixins\Weaving\CompositeMixinsWeaverBuilder.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Framework\CompositeRuntime.cs" />
<Compile Include="Properties\Resources.Designer.cs">
Expand All @@ -121,11 +123,13 @@
<DependentUpon>Resources.resx</DependentUpon>
</Compile>
<Compile Include="Runtime\CompositeRuntimeSettings.cs" />
<Compile Include="Weaving\AtomMixinsWeaverStartegy.cs" />
<Compile Include="Weaving\CompositeMethodWeaver.cs" />
<Compile Include="Weaving\CompositeMethodWeaverBuilder.cs" />
<Compile Include="Weaving\CompositeTypeWeaverBuilder.cs" />
<Compile Include="Weaving\CompositePropertyWeaverBuilder.cs" />
<Compile Include="Weaving\CompositeWeavinsSettings.cs" />
<Compile Include="Mixins\Weaving\ICompositeMixinsTypeWeaverBuilder.cs" />
<Compile Include="Weaving\ICompositeWeavingSettings.cs" />
</ItemGroup>
<ItemGroup>
Expand Down
42 changes: 42 additions & 0 deletions NCop.Composite/Weaving/AtomMixinsWeaverStartegy.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using NCop.Core;
using NCop.Weaving;
using NCop.Core.Extensions;
using System;
using NCop.Mixins.Engine;
using NCop.IoC;

namespace NCop.Composite.Weaving
{
internal class AtomMixinsWeaverStartegy : ITypeWeaver
{
private readonly TypeMap mixin = null;
private readonly ITypeDefinition typeDefinition = null;
private readonly INCopDependencyAwareRegistry registry = null;
private readonly IEnumerable<IMethodWeaver> methodWeavers = null;

internal AtomMixinsWeaverStartegy(ITypeDefinition typeDefinition, TypeMap mixin, IEnumerable<IMethodWeaver> methodWeavers, INCopDependencyAwareRegistry registry) {
this.mixin = mixin;
this.registry = registry;
this.methodWeavers = methodWeavers;
this.typeDefinition = typeDefinition;
}

public void Weave() {
Type weavedType = null;

methodWeavers.ForEach(methodWeaver => {
var methodBuilder = methodWeaver.DefineMethod();
var ilGenerator = methodBuilder.GetILGenerator();

methodWeaver.WeaveMethodScope(ilGenerator);
methodWeaver.WeaveEndMethod(ilGenerator);
});

weavedType = typeDefinition.TypeBuilder.CreateType();
registry.Register(weavedType, typeDefinition.Type, new TypeMapSet { mixin });
}
}
}
20 changes: 18 additions & 2 deletions NCop.Composite/Weaving/CompositeTypeWeaverBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,13 @@
using NCop.Mixins.Weaving;
using NCop.Weaving;
using NCop.Aspects.Weaving;
using NCop.Composite.Mixins.Weaving;

namespace NCop.Composite.Weaving
{
internal class CompositeTypeWeaverBuilder : ITypeWeaverBuilder
{
private readonly MixinsTypeWeaverBuilder builder = null;
private readonly ICompositeMixinsTypeWeaverBuilder builder = null;

internal CompositeTypeWeaverBuilder(ICompositeWeavingSettings compositeWeavingSettings) {
var registry = compositeWeavingSettings.Registry;
Expand All @@ -28,7 +29,12 @@ internal CompositeTypeWeaverBuilder(ICompositeWeavingSettings compositeWeavingSe
var compositeMappedMembers = new CompositeMemberMapper(aspectsMap, aspectMappedMembers);
var typeDefinition = typeDefinitionWeaver.Weave();

builder = new MixinsTypeWeaverBuilder(compositeType, typeDefinition, registry);
if (IsAtomComposite(compositeType, mixinsMap)) {
builder = new AtomCompositeMixinsWeaverBuilder(compositeType, typeDefinition, registry);
}
else {
builder = new CompositeMixinsWeaverBuilder(compositeType, typeDefinition, registry);
}

mixinsMap.ForEach(map => {
builder.Add(map);
Expand All @@ -50,5 +56,15 @@ internal CompositeTypeWeaverBuilder(ICompositeWeavingSettings compositeWeavingSe
public ITypeWeaver Build() {
return builder.Build();
}

private bool IsAtomComposite(Type compositeType, ITypeMap mixinsMap) {
if (mixinsMap.Count == 1) {
var mixinMap = mixinsMap.First();

return mixinMap.ContractType.Equals(compositeType);
}

return false;
}
}
}
2 changes: 1 addition & 1 deletion NCop.Core/AttributeTypeMatcher.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ public AttributeTypeMatcher(Type type, Func<TAttribute, Type[]> typeFactory) {
ISet<Type> mappedInterfaces = null;

this.typeFactory = typeFactory;
interfaces = type.GetInterfaces().ToSet();
interfaces = type.GetInterfacesAndSelf().ToSet();
map.AddRange(FindTypesRecursively(type));
mappedInterfaces = GetMappedInterfaces(interfaces.Concat(type));

Expand Down
15 changes: 15 additions & 0 deletions NCop.Core/Extensions/ReflectionExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,21 @@ public static IEnumerable<Type> GetImmediateInterfaces(this Type type) {
return nonInheritedInterfaces;
}

public static IEnumerable<Type> GetInterfacesAndSelf(this Type type) {
var interfaces = type.GetInterfaces();
var nonInheritedInterfaces = new HashSet<Type>(interfaces);

if (type.IsInterface) {
nonInheritedInterfaces.Add(type);
}

foreach (var @interface in interfaces) {
@interface.RemoveInheritedInterfaces(nonInheritedInterfaces);
}

return nonInheritedInterfaces;
}

public static bool HasCovariantType(this ISet<Type> set, Type inspected) {
return set.Any(item => {
return inspected.IsCovariantTo(item);
Expand Down
1 change: 0 additions & 1 deletion NCop.Mixins/Engine/IMixinMapBag.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,5 @@ namespace NCop.Mixins.Engine
{
public interface IMixinMapBag : IBag<TypeMap>
{

}
}
Loading

0 comments on commit 531a560

Please sign in to comment.