Skip to content

Commit

Permalink
Resolve #218: Module.AttachToComponentRegistration() detects registra…
Browse files Browse the repository at this point in the history
…tions in nested scopes
  • Loading branch information
tillig authored Nov 1, 2018
2 parents e7c821c + 3266995 commit b65821a
Show file tree
Hide file tree
Showing 3 changed files with 95 additions and 4 deletions.
2 changes: 2 additions & 0 deletions src/Autofac/Builder/MetadataKeys.cs
Original file line number Diff line number Diff line change
Expand Up @@ -34,5 +34,7 @@ internal static class MetadataKeys
internal const string StartOnActivatePropertyKey = "__StartOnActivate";

internal const string ContainerBuildOptions = "__ContainerBuildOptions";

internal const string RegisteredPropertyKey = "__RegisteredKey";
}
}
32 changes: 28 additions & 4 deletions src/Autofac/Core/Registration/ComponentRegistry.cs
Original file line number Diff line number Diff line change
Expand Up @@ -207,8 +207,7 @@ protected virtual void AddRegistration(IComponentRegistration registration, bool

_registrations.Add(registration);

var handler = Registered;
handler?.Invoke(this, new ComponentRegisteredEventArgs(this, registration));
GetRegistered()?.Invoke(this, new ComponentRegisteredEventArgs(this, registration));
}

/// <summary>
Expand Down Expand Up @@ -266,7 +265,24 @@ public IEnumerable<IComponentRegistration> DecoratorsFor(IComponentRegistration
/// Fired whenever a component is registered - either explicitly or via a
/// <see cref="IRegistrationSource"/>.
/// </summary>
public event EventHandler<ComponentRegisteredEventArgs> Registered;
public event EventHandler<ComponentRegisteredEventArgs> Registered
{
add
{
lock (_synchRoot)
{
Properties[MetadataKeys.RegisteredPropertyKey] = GetRegistered() + value;
}
}

remove
{
lock (_synchRoot)
{
Properties[MetadataKeys.RegisteredPropertyKey] = GetRegistered() - value;
}
}
}

/// <summary>
/// Add a registration source that will provide registrations on-the-fly.
Expand Down Expand Up @@ -360,5 +376,13 @@ private ServiceRegistrationInfo GetServiceInfo(Service service)
_serviceInfo.Add(service, info);
return info;
}

private EventHandler<ComponentRegisteredEventArgs> GetRegistered()
{
if (Properties.TryGetValue(MetadataKeys.RegisteredPropertyKey, out var registered))
return (EventHandler<ComponentRegisteredEventArgs>)registered;

return null;
}
}
}
}
65 changes: 65 additions & 0 deletions test/Autofac.Test/ModuleTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using Autofac.Builder;
using Autofac.Core;
using Autofac.Core.Registration;
using Xunit;
Expand Down Expand Up @@ -59,6 +60,70 @@ public void AttachesToRegistrations()
Assert.Equal(container.ComponentRegistry.Registrations.Count(), attachingModule.Registrations.Count);
}

[Fact]
public void AttachesToRegistrationsInScope()
{
var attachingModule = new AttachingModule();
Assert.Equal(0, attachingModule.Registrations.Count);

var builder = new ContainerBuilder();
builder.RegisterModule(attachingModule);

using (var container = builder.Build())
using (var scope = container.BeginLifetimeScope(c => c.RegisterType(typeof(int))))
{
var expected = container.ComponentRegistry.Registrations.Count() + scope.ComponentRegistry.Registrations.Count();
Assert.Equal(expected, attachingModule.Registrations.Count);
}
}

[Fact]
public void AttachesToRegistrationsInNestedScope()
{
var attachingModule = new AttachingModule();
Assert.Equal(0, attachingModule.Registrations.Count);

var builder = new ContainerBuilder();
builder.RegisterModule(attachingModule);

using (var container = builder.Build())
using (var outerScope = container.BeginLifetimeScope(c => c.RegisterType(typeof(int))))
using (var innerScope = outerScope.BeginLifetimeScope(c => c.RegisterType(typeof(double))))
{
var expected = container.ComponentRegistry.Registrations.Count()
+ outerScope.ComponentRegistry.Registrations.Count() + innerScope.ComponentRegistry.Registrations.Count();
Assert.Equal(expected, attachingModule.Registrations.Count);
}
}

[Fact]
public void ModifiedScopesHaveTheirOwnDelegate()
{
var attachingModule = new AttachingModule();
Assert.Equal(0, attachingModule.Registrations.Count);

var builder = new ContainerBuilder();
builder.RegisterModule(attachingModule);

using (var container = builder.Build())
{
Assert.NotNull(container.ComponentRegistry.Properties[MetadataKeys.RegisteredPropertyKey]);
using (var outerScope = container.BeginLifetimeScope(c => c.RegisterType(typeof(int))))
{
Assert.Equal(
container.ComponentRegistry.Properties[MetadataKeys.RegisteredPropertyKey],
outerScope.ComponentRegistry.Properties[MetadataKeys.RegisteredPropertyKey]);
outerScope.ComponentRegistry.Registered += (s, e) => { };
using (var innerScope = outerScope.BeginLifetimeScope())
{
Assert.NotEqual(
container.ComponentRegistry.Properties[MetadataKeys.RegisteredPropertyKey],
innerScope.ComponentRegistry.Properties[MetadataKeys.RegisteredPropertyKey]);
}
}
}
}

internal class ModuleExposingThisAssembly : Module
{
public Assembly ModuleThisAssembly
Expand Down

0 comments on commit b65821a

Please sign in to comment.