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