From 997153d956bf18deb498ca5cf933f825c7949552 Mon Sep 17 00:00:00 2001
From: Eugene Baranov <220614+eugbaranov@users.noreply.github.com>
Date: Tue, 30 Oct 2018 00:33:31 +0000
Subject: [PATCH] Inherit Registered callback in child scopes (closes #218)
---
src/Autofac/Builder/MetadataKeys.cs | 2 ++
.../Core/Registration/ComponentRegistry.cs | 32 ++++++++++++++---
test/Autofac.Test/ModuleTests.cs | 36 +++++++++++++++++++
3 files changed, 66 insertions(+), 4 deletions(-)
diff --git a/src/Autofac/Builder/MetadataKeys.cs b/src/Autofac/Builder/MetadataKeys.cs
index 8e068b9a0..1465a7f91 100644
--- a/src/Autofac/Builder/MetadataKeys.cs
+++ b/src/Autofac/Builder/MetadataKeys.cs
@@ -34,5 +34,7 @@ internal static class MetadataKeys
internal const string StartOnActivatePropertyKey = "__StartOnActivate";
internal const string ContainerBuildOptions = "__ContainerBuildOptions";
+
+ internal const string RegisteredPropertyKey = "__RegisteredKey";
}
}
diff --git a/src/Autofac/Core/Registration/ComponentRegistry.cs b/src/Autofac/Core/Registration/ComponentRegistry.cs
index 4cf9ebd8d..f4ba4fa2e 100644
--- a/src/Autofac/Core/Registration/ComponentRegistry.cs
+++ b/src/Autofac/Core/Registration/ComponentRegistry.cs
@@ -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));
}
///
@@ -266,7 +265,24 @@ public IEnumerable DecoratorsFor(IComponentRegistration
/// Fired whenever a component is registered - either explicitly or via a
/// .
///
- public event EventHandler Registered;
+ public event EventHandler Registered
+ {
+ add
+ {
+ lock (_synchRoot)
+ {
+ Properties[MetadataKeys.RegisteredPropertyKey] = GetRegistered() + value;
+ }
+ }
+
+ remove
+ {
+ lock (_synchRoot)
+ {
+ Properties[MetadataKeys.RegisteredPropertyKey] = GetRegistered() - value;
+ }
+ }
+ }
///
/// Add a registration source that will provide registrations on-the-fly.
@@ -360,5 +376,13 @@ private ServiceRegistrationInfo GetServiceInfo(Service service)
_serviceInfo.Add(service, info);
return info;
}
+
+ private EventHandler GetRegistered()
+ {
+ if (Properties.TryGetValue(MetadataKeys.RegisteredPropertyKey, out var registered))
+ return (EventHandler)registered;
+
+ return null;
+ }
}
-}
+}
\ No newline at end of file
diff --git a/test/Autofac.Test/ModuleTests.cs b/test/Autofac.Test/ModuleTests.cs
index 3b25ae0cd..c5d4406a1 100644
--- a/test/Autofac.Test/ModuleTests.cs
+++ b/test/Autofac.Test/ModuleTests.cs
@@ -59,6 +59,42 @@ 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);
+ }
+ }
+
internal class ModuleExposingThisAssembly : Module
{
public Assembly ModuleThisAssembly