Hi folks. I'm currently enjoying the AutoMockingContainer found in
RhinoTesting (although a binary download against the current released
dlls would be nice).

I'm missing support for non-public constructors. I want to write code
that has a default constructor that provides the dependencies to an
internal constructor. In production code, I use the default
constructor. In test code, I use the internal constructor. The current
AutoMockingContainer doesn't know how to handle this usage - it only
works with public constructors.

This patch allows for internal (and even private!) constructors. Hope
the paste works:

Index: Rhino.Testing.Tests/AutoMocking/AddComponentInstanceFixture.cs
===================================================================
--- Rhino.Testing.Tests/AutoMocking/AddComponentInstanceFixture.cs
(revision 1715)
+++ Rhino.Testing.Tests/AutoMocking/AddComponentInstanceFixture.cs
(working copy)
@@ -1,31 +1,34 @@
 using MbUnit.Framework;
-using Rhino.Mocks;
-using Rhino.Testing.AutoMocking;
-
-[TestFixture]
-public class AddComponentInstanceFixture
-{
-       private AutoMockingContainer container;
-       private MockRepository mocks;
-
-       public class InstancedComponent
-       {
-       }
-
-       [SetUp]
-       public void SetUp()
-       {
-               mocks = new MockRepository();
-               container = new AutoMockingContainer(mocks);
-               container.Initialize();
-       }
-
-
-       [Test]
-       public void AddComponentInstance_CanBeRetrieved()
-       {
-               InstancedComponent component = new InstancedComponent();
-               container.Kernel.AddComponentInstance("InstancedComponent", 
typeof
(InstancedComponent), component);
-               Assert.AreEqual(component, container.Get<InstancedComponent>());
-       }
+using Rhino.Mocks;
+using Rhino.Testing.AutoMocking;
+
+namespace Rhino.Testing.Tests.AutoMocking
+{
+    [TestFixture]
+    public class AddComponentInstanceFixture
+    {
+        private AutoMockingContainer container;
+        private MockRepository mocks;
+
+        public class InstancedComponent
+        {
+        }
+
+        [SetUp]
+        public void SetUp()
+        {
+            mocks = new MockRepository();
+            container = new AutoMockingContainer(mocks);
+            container.Initialize();
+        }
+
+
+        [Test]
+        public void AddComponentInstance_CanBeRetrieved()
+        {
+            InstancedComponent component = new InstancedComponent();
+
container.Kernel.AddComponentInstance("InstancedComponent",
typeof(InstancedComponent), component);
+            Assert.AreEqual(component,
container.Get<InstancedComponent>());
+        }
+    }
 }
\ No newline at end of file
Index: Rhino.Testing.Tests/AutoMocking/AutoMockingContainerTests.cs
===================================================================
--- Rhino.Testing.Tests/AutoMocking/AutoMockingContainerTests.cs
(revision 1715)
+++ Rhino.Testing.Tests/AutoMocking/AutoMockingContainerTests.cs
(working copy)
@@ -27,7 +27,40 @@

            }

-           [Test]
+        // It might be nice to test this on a class in a separate
assembly...
+        [Test]
+        public void
Create_WillResolveDependenciesOnInternalClassWithInternalConstructor()
+        {
+            InternalComponentBeingConfigured target =
container.Create<InternalComponentBeingConfigured>();
+            Assert.IsNotNull(target.ReallyCoolService, "mocked
ReallyCoolService dependency");
+            Assert.IsNotNull(target.Services, "mocked Services
dependency");
+        }
+
+        [Test]
+        public void
Create_WillResolveDependenciesPreferringInternalConstructor()
+        {
+            ComponentBeingConfiguredWithInternalCtor target =
container.Create<ComponentBeingConfiguredWithInternalCtor>();
+            Assert.IsNotNull(target.ReallyCoolService, "mocked
ReallyCoolService dependency");
+            Assert.IsNotNull(target.Services, "mocked Services
dependency");
+        }
+
+        [Test]
+        public void
Create_WillResolveDependenciesPreferringInternalConstructor_WithResolvePropertiesEnabled()
+        {
+            ComponentBeingConfiguredWithInternalCtor target =
containerThatResolvesProperties.Create<ComponentBeingConfiguredWithInternalCtor>();
+            Assert.IsNotNull(target.ReallyCoolService, "mocked
ReallyCoolService dependency");
+            Assert.IsNotNull(target.Services, "mocked Services
dependency");
+        }
+
+        [Test]
+        public void
Create_WillResolveDependenciesPreferringPrivateConstructor()
+        {
+            ComponentBeingConfiguredWithPrivateCtor target =
container.Create<ComponentBeingConfiguredWithPrivateCtor>();
+            Assert.IsNotNull(target.ReallyCoolService, "mocked
ReallyCoolService dependency");
+            Assert.IsNotNull(target.Services, "mocked Services
dependency");
+        }
+
+        [Test]
         public void Create_WillResolveDependenciesAsMocks_ByDefault()
            {
             ComponentBeingConfigured target =
container.Create<ComponentBeingConfigured>();
Index: Rhino.Testing.Tests/AutoMocking/ComponentBeingConfigured.cs
===================================================================
--- Rhino.Testing.Tests/AutoMocking/ComponentBeingConfigured.cs
(revision 1715)
+++ Rhino.Testing.Tests/AutoMocking/ComponentBeingConfigured.cs
(working copy)
@@ -11,7 +11,6 @@
             Services = services;
         }

-
         public ComponentBeingConfigured(IReallyCoolService
reallyCoolService)
         {
             ReallyCoolService = reallyCoolService;
Index: Rhino.Testing.Tests/AutoMocking/
ComponentBeingConfiguredWithInternalCtor.cs
===================================================================
--- Rhino.Testing.Tests/AutoMocking/
ComponentBeingConfiguredWithInternalCtor.cs     (revision 0)
+++ Rhino.Testing.Tests/AutoMocking/
ComponentBeingConfiguredWithInternalCtor.cs     (revision 0)
@@ -0,0 +1,24 @@
+namespace Rhino.Testing.Tests.AutoMocking
+{
+    public class ComponentBeingConfiguredWithInternalCtor
+    {
+        public IReallyCoolService ReallyCoolService;
+        public ICollectionOfServices Services;
+
+        internal
ComponentBeingConfiguredWithInternalCtor(IReallyCoolService
reallyCoolService, ICollectionOfServices services)
+        {
+            ReallyCoolService = reallyCoolService;
+            Services = services;
+        }
+
+        public
ComponentBeingConfiguredWithInternalCtor(IReallyCoolService
reallyCoolService)
+        {
+            ReallyCoolService = reallyCoolService;
+        }
+
+        public void RunDispose()
+        {
+            Services.SomethingToDispose.Dispose();
+        }
+    }
+}
\ No newline at end of file
Index: Rhino.Testing.Tests/AutoMocking/
ComponentBeingConfiguredWithPrivateCtor.cs
===================================================================
--- Rhino.Testing.Tests/AutoMocking/
ComponentBeingConfiguredWithPrivateCtor.cs      (revision 0)
+++ Rhino.Testing.Tests/AutoMocking/
ComponentBeingConfiguredWithPrivateCtor.cs      (revision 0)
@@ -0,0 +1,23 @@
+namespace Rhino.Testing.Tests.AutoMocking
+{
+    public class ComponentBeingConfiguredWithPrivateCtor
+    {
+        public IReallyCoolService ReallyCoolService;
+        public ICollectionOfServices Services;
+
+        private
ComponentBeingConfiguredWithPrivateCtor(IReallyCoolService
reallyCoolService, ICollectionOfServices services)
+        {
+            ReallyCoolService = reallyCoolService;
+            Services = services;
+        }
+
+        public
ComponentBeingConfiguredWithPrivateCtor(IReallyCoolService
reallyCoolService) : this(reallyCoolService, null)
+        {
+        }
+
+        public void RunDispose()
+        {
+            Services.SomethingToDispose.Dispose();
+        }
+    }
+}
\ No newline at end of file
Index: Rhino.Testing.Tests/AutoMocking/
InternalComponentBeingConfigured.cs
===================================================================
--- Rhino.Testing.Tests/AutoMocking/
InternalComponentBeingConfigured.cs     (revision 0)
+++ Rhino.Testing.Tests/AutoMocking/
InternalComponentBeingConfigured.cs     (revision 0)
@@ -0,0 +1,19 @@
+namespace Rhino.Testing.Tests.AutoMocking
+{
+    internal class InternalComponentBeingConfigured
+    {
+        public IReallyCoolService ReallyCoolService;
+        public ICollectionOfServices Services;
+
+        internal InternalComponentBeingConfigured(IReallyCoolService
reallyCoolService, ICollectionOfServices services)
+        {
+            ReallyCoolService = reallyCoolService;
+            Services = services;
+        }
+
+        public void RunDispose()
+        {
+            Services.SomethingToDispose.Dispose();
+        }
+    }
+}
\ No newline at end of file
Index: Rhino.Testing.Tests/Rhino.Testing.Tests-vs2008.csproj
===================================================================
--- Rhino.Testing.Tests/Rhino.Testing.Tests-vs2008.csproj       (revision
1715)
+++ Rhino.Testing.Tests/Rhino.Testing.Tests-vs2008.csproj       (working
copy)
@@ -79,9 +79,12 @@
     <Compile Include="AutoMocking\AutoMockingContainerTests.cs" />
     <Compile Include="AutoMocking\AutoMockingTests.cs" />
     <Compile Include="AutoMocking\ComponentBeingConfigured.cs" />
+    <Compile Include="AutoMocking
\ComponentBeingConfiguredWithInternalCtor.cs" />
+    <Compile Include="AutoMocking
\ComponentBeingConfiguredWithPrivateCtor.cs" />
     <Compile Include="AutoMocking\ComponentWithComplexProperty.cs" />
     <Compile Include="AutoMocking\DefaultCollectionOfServices.cs" />
     <Compile Include="AutoMocking\ICollectionOfServices.cs" />
+    <Compile Include="AutoMocking
\InternalComponentBeingConfigured.cs" />
     <Compile Include="AutoMocking\IReallyCoolService.cs" />
     <Compile Include="AutoMocking\NeedIKernel.cs" />
     <Compile Include="CommentReaderFixture.cs" />
@@ -118,4 +121,4 @@
   <Target Name="AfterBuild">
   </Target>
   -->
-</Project>
+</Project>
\ No newline at end of file
Index: Rhino.Testing/AutoMocking/AutoMockingComponentActivator.cs
===================================================================
--- Rhino.Testing/AutoMocking/AutoMockingComponentActivator.cs
(revision 1715)
+++ Rhino.Testing/AutoMocking/AutoMockingComponentActivator.cs
(working copy)
@@ -1,3 +1,5 @@
+using System;
+using System.Reflection;
 using Castle.Core;
 using Castle.MicroKernel;
 using Castle.MicroKernel.ComponentActivator;
@@ -12,9 +14,14 @@
                {
                }

-               protected override void SetUpProperties(object instance,
CreationContext context)
-               {
+        protected override object CreateInstance(CreationContext
context, object[] arguments, System.Type[] signature)
+        {
+            // TODO: Support interceptors + copy "use fast create
instance" logic from DefaultComponentActivator

-               }
+            // Support internal and private constructors
+            return Activator.CreateInstance(Model.Implementation,
+
BindingFlags.CreateInstance | BindingFlags.NonPublic |
BindingFlags.Public |
+                                            BindingFlags.Instance,
null, arguments, null, null);
+        }
        }
 }
Index: Rhino.Testing/AutoMocking/AutoMockingContainer.cs
===================================================================
--- Rhino.Testing/AutoMocking/AutoMockingContainer.cs   (revision 1715)
+++ Rhino.Testing/AutoMocking/AutoMockingContainer.cs   (working copy)
@@ -2,10 +2,8 @@
 using System.Collections;
 using System.Collections.Generic;
 using Castle.MicroKernel;
-using Castle.MicroKernel.SubSystems.Naming;
 using Castle.Windsor;
 using Rhino.Mocks;
-using System.Diagnostics;

 namespace Rhino.Testing.AutoMocking
 {
@@ -92,6 +90,7 @@
                {
                        Kernel.AddSubSystem(SubSystemConstants.NamingKey,new
AutoMockingNamingSubSystem(this));
                        Kernel.AddFacility("AutoMockingFacility", new
AutoMockingFacility(this));
+                   Kernel.ComponentModelBuilder.AddContributor(new
NonPublicConstructorDependenciesModelInspector());
                        Kernel.ComponentModelCreated += 
Kernel_ComponentModelCreated;
                }

@@ -99,8 +98,9 @@
                {
                        if (model.CustomComponentActivator!=null)
                                return;
-            if (!ResolveProperties)
-                model.CustomComponentActivator =
typeof(AutoMockingComponentActivator);
+                   model.CustomComponentActivator = ResolveProperties
+                                                        ? typeof
(AutoMockingComponentActivator)
+                                                        : typeof
(NonPropertyResolvingComponentActivator);
                }

                private void AddComponentIfMissing<T>()
Index: Rhino.Testing/AutoMocking/
NonPropertyResolvingComponentActivator.cs
===================================================================
--- Rhino.Testing/AutoMocking/
NonPropertyResolvingComponentActivator.cs       (revision 0)
+++ Rhino.Testing/AutoMocking/
NonPropertyResolvingComponentActivator.cs       (revision 0)
@@ -0,0 +1,18 @@
+using Castle.Core;
+using Castle.MicroKernel;
+
+namespace Rhino.Testing.AutoMocking
+{
+    class NonPropertyResolvingComponentActivator :
AutoMockingComponentActivator
+    {
+        public NonPropertyResolvingComponentActivator(ComponentModel
model, IKernel kernel, ComponentInstanceDelegate onCreation,
ComponentInstanceDelegate onDestruction)
+            : base(model, kernel, onCreation, onDestruction)
+        {
+        }
+
+        protected override void SetUpProperties(object instance,
CreationContext context)
+        {
+            // Do nothing - we're not resolving properties
+        }
+    }
+}
\ No newline at end of file
Index: Rhino.Testing/AutoMocking/
NonPublicConstructorDependenciesModelInspector.cs
===================================================================
--- Rhino.Testing/AutoMocking/
NonPublicConstructorDependenciesModelInspector.cs       (revision 0)
+++ Rhino.Testing/AutoMocking/
NonPublicConstructorDependenciesModelInspector.cs       (revision 0)
@@ -0,0 +1,18 @@
+using System.Reflection;
+using Castle.MicroKernel;
+using Castle.MicroKernel.ModelBuilder.Inspectors;
+
+namespace Rhino.Testing.AutoMocking
+{
+    internal class NonPublicConstructorDependenciesModelInspector :
ConstructorDependenciesModelInspector
+    {
+        public override void ProcessModel(IKernel kernel,
Castle.Core.ComponentModel model)
+        {
+            base.ProcessModel(kernel, model);
+
+            var constructors =
model.Implementation.GetConstructors(BindingFlags.Instance |
BindingFlags.NonPublic);
+            foreach (var constructorInfo in constructors)
+
model.Constructors.Add(CreateConstructorCandidate(model,
constructorInfo));
+        }
+    }
+}
\ No newline at end of file

Property changes on: Rhino.Testing\AutoMocking
\NonPublicConstructorDependenciesModelInspector.cs
___________________________________________________________________
Added: svn:mergeinfo

Index: Rhino.Testing/Rhino.Testing-v2008.csproj
===================================================================
--- Rhino.Testing/Rhino.Testing-v2008.csproj    (revision 1715)
+++ Rhino.Testing/Rhino.Testing-v2008.csproj    (working copy)
@@ -81,6 +81,8 @@
     <Compile Include="AutoMocking\IAutoMockingRepository.cs" />
     <Compile Include="AutoMocking\IMockingStrategy.cs" />
     <Compile Include="AutoMocking\NonMockedStrategy.cs" />
+    <Compile Include="AutoMocking
\NonPropertyResolvingComponentActivator.cs" />
+    <Compile Include="AutoMocking
\NonPublicConstructorDependenciesModelInspector.cs" />
     <Compile Include="AutoMocking\TypeMarker.cs" />
     <Compile Include="CommentReader.cs" />
     <Compile Include="Properties\AssemblyInfo.cs" />
@@ -115,4 +117,4 @@
   <Target Name="AfterBuild">
   </Target>
   -->
-</Project>
+</Project>
\ No newline at end of file



Cheers
Matt

--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups 
"Rhino.Mocks" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/RhinoMocks?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to