User: xtoff
Date: 2009/12/10 02:10 PM

Added:
 /InversionOfControl/trunk/src/Castle.MicroKernel.Tests/ClassComponents/
  ClassWithArguments.cs
 /InversionOfControl/trunk/src/Castle.MicroKernel.Tests/Registration/
  WithParametersTestCase.cs
 /InversionOfControl/trunk/src/Castle.MicroKernel/Registration/
  WithParametersDescriptor.cs

Removed:
 /InversionOfControl/trunk/src/Castle.MicroKernel.Tests/Facilities/OnCreate/

Modified:
 /InversionOfControl/trunk/src/
  Changes.txt, InversionOfControl-vs2008.sln
 /InversionOfControl/trunk/src/Castle.MicroKernel.Tests/
  Castle.MicroKernel.Tests-vs2008.csproj
 /InversionOfControl/trunk/src/Castle.MicroKernel/
  Castle.MicroKernel-vs2008.csproj
 /InversionOfControl/trunk/src/Castle.MicroKernel/Context/
  CreationContext.cs
 /InversionOfControl/trunk/src/Castle.MicroKernel/Handlers/
  AbstractHandler.cs, DefaultGenericHandler.cs, DefaultHandler.cs
 /InversionOfControl/trunk/src/Castle.MicroKernel/Registration/
  ComponentRegistration.cs

Log:
 - added WithParameters method to fluent registration that enables inspecting 
and modifying arguments passed to Resolve method.
 - BREAKING CHANGE - AbstractHandler.Resolve method is no longer abstract and 
instead a ResolveCore protected abstract method was added. To fix this, 
implementers should override ResolveCore instead of Resolve.

File Changes:

Directory: /InversionOfControl/trunk/src/Castle.MicroKernel/
============================================================

File [modified]: Castle.MicroKernel-vs2008.csproj
Delta lines: +21 -1
===================================================================

--- InversionOfControl/trunk/src/Castle.MicroKernel/Context/CreationContext.cs  
2009-12-10 19:50:49 UTC (rev 6399)
+++ InversionOfControl/trunk/src/Castle.MicroKernel/Context/CreationContext.cs  
2009-12-10 21:10:17 UTC (rev 6400)
@@ -17,6 +17,8 @@
        using System;
        using System.Collections;
        using System.Collections.Generic;
+       using System.Collections.Specialized;
+
        using Castle.Core;
        using Releasers;
        using SubSystems.Conversion;
@@ -88,13 +90,31 @@
                {
                        this.handler = handler;
                        this.releasePolicy = releasePolicy;
-                       this.additionalArguments = additionalArguments;
+                       this.additionalArguments = 
EnsureWriteable(additionalArguments);
                        this.converter = conversionManager;
                        dependencies = new DependencyModelCollection();
 
                        genericArguments = 
ExtractGenericArguments(typeToExtractGenericArguments);
                }
 
+               private IDictionary EnsureWriteable(IDictionary dictionary)
+               {
+                       // NOTE: this is actually here mostly to workaround the 
fact that ReflectionBasedDictionaryAdapter is read only
+                       // we could make it writeable instead, but I'm not sure 
that would make sense.
+                       if (dictionary == null)
+                       {
+                               // two should be enought for most cases
+                               return new HybridDictionary(2);
+                       }
+
+                       if (!dictionary.IsReadOnly)
+                       {
+                               return dictionary;
+                       }
+
+                       return new Hashtable(dictionary);
+               }
+
                /// <summary>
                /// Initializes a new instance of the <see 
cref="CreationContext"/> class.

Directory: /InversionOfControl/trunk/src/Castle.MicroKernel.Tests/
==================================================================

File [modified]: Castle.MicroKernel.Tests-vs2008.csproj
Delta lines: +38 -0
===================================================================

--- 
InversionOfControl/trunk/src/Castle.MicroKernel.Tests/ClassComponents/ClassWithArguments.cs
                         (rev 0)
+++ 
InversionOfControl/trunk/src/Castle.MicroKernel.Tests/ClassComponents/ClassWithArguments.cs
 2009-12-10 21:10:17 UTC (rev 6400)
@@ -0,0 +1,38 @@
+// Copyright 2004-2009 Castle Project - http://www.castleproject.org/
+// 
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+// 
+//     http://www.apache.org/licenses/LICENSE-2.0
+// 
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+namespace Castle.MicroKernel.Tests.ClassComponents
+{
+       public class ClassWithArguments
+       {
+               private readonly string arg1;
+               private readonly int arg2;
+
+               public string Arg1
+               {
+                       get { return arg1; }
+               }
+
+               public int Arg2
+               {
+                       get { return arg2; }
+               }
+
+               public ClassWithArguments(string arg1, int arg2)
+               {
+                       this.arg1 = arg1;
+                       this.arg2 = arg2;
+               }
+       }
+}

Directory: 
/InversionOfControl/trunk/src/Castle.MicroKernel.Tests/ClassComponents/
==================================================================================

File [added]: ClassWithArguments.cs
Delta lines: +121 -0
===================================================================

--- 
InversionOfControl/trunk/src/Castle.MicroKernel.Tests/Registration/WithParametersTestCase.cs
                                (rev 0)
+++ 
InversionOfControl/trunk/src/Castle.MicroKernel.Tests/Registration/WithParametersTestCase.cs
        2009-12-10 21:10:17 UTC (rev 6400)
@@ -0,0 +1,121 @@
+// Copyright 2004-2009 Castle Project - http://www.castleproject.org/
+// 
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+// 
+//     http://www.apache.org/licenses/LICENSE-2.0
+// 
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+namespace Castle.MicroKernel.Tests.Registration
+{
+       using Castle.MicroKernel.Registration;
+       using Castle.MicroKernel.Tests.ClassComponents;
+
+       using NUnit.Framework;
+
+       [TestFixture]
+       public class WithParametersTestCase
+       {
+               [SetUp]
+               public void SetUp()
+               {
+                       kernel = new DefaultKernel();
+               }
+
+               [TearDown]
+               public void TearDown()
+               {
+                       kernel.Dispose();
+               }
+
+               private DefaultKernel kernel;
+
+               [Test]
+               public void Can_mix_registration_and_call_site_parameters()
+               {
+                       
kernel.Register(Component.For<ClassWithArguments>().LifeStyle.Transient.WithParameters((k,
 d) => d["arg1"] = "foo"));
+
+                       var component = kernel.Resolve<ClassWithArguments>(new 
{ arg2 = 2 });
+                       Assert.AreEqual(2, component.Arg2);
+                       Assert.AreEqual("foo", component.Arg1);
+               }
+
+               [Test]
+               public void 
Should_have_access_to_parameters_passed_from_call_site()
+               {
+                       string arg1 = null;
+                       int arg2 = 0;
+                       
kernel.Register(Component.For<ClassWithArguments>().LifeStyle.Transient.WithParameters((k,
 d) =>
+                       {
+                               arg1 = (string)d["arg1"];
+                               arg2 = (int)d["arg2"];
+                       }));
+                       var component = kernel.Resolve<ClassWithArguments>(new 
{ arg2 = 2, arg1 = "foo" });
+                       Assert.AreEqual("foo", arg1);
+                       Assert.AreEqual(2, arg2);
+               }
+
+               [Test]
+               public void Should_not_require_explicit_registration()
+               {
+                       
kernel.Register(Component.For<CommonSub2Impl>().LifeStyle.Transient.WithParameters((k,
 d) => { }));
+                       Assert.DoesNotThrow(() => 
kernel.Resolve<CommonSub2Impl>());
+               }
+
+               [Test]
+               public void Should_override_parameters_passed_from_call_site()
+               {
+                       string arg1 = "bar";
+                       int arg2 = 5;
+                       
kernel.Register(Component.For<ClassWithArguments>().LifeStyle.Transient.WithParameters((k,
 d) =>
+                       {
+                               d["arg1"] = arg1;
+                               d["arg2"] = arg2;
+                       }));
+                       var component = kernel.Resolve<ClassWithArguments>(new 
{ arg2 = 2, arg1 = "foo" });
+                       Assert.AreEqual(arg1, component.Arg1);
+                       Assert.AreEqual(arg2, component.Arg2);
+               }
+
+               [Test]
+               public void Should_handle_multiple_calls()
+               {
+                       string arg1 = "bar";
+                       int arg2 = 5;
+                       kernel.Register(Component.For<ClassWithArguments>()
+                                               .LifeStyle.Transient
+                                               .WithParameters((k, d) =>
+                                               {
+                                                       d["arg1"] = arg1;
+                                               })
+                                               .WithParameters((k, d) =>
+                                               {
+                                                       d["arg2"] = arg2;
+                                               }));
+                       var component = kernel.Resolve<ClassWithArguments>(new 
{ arg2 = 2, arg1 = "foo" });
+                       Assert.AreEqual(arg1, component.Arg1);
+                       Assert.AreEqual(arg2, component.Arg2);
+               }
+
+               [Test]
+               public void 
Should_resolve_component_when_no_parameters_passed_from_call_site()
+               {
+                       string arg1 = "bar";
+                       int arg2 = 5;
+                       
kernel.Register(Component.For<ClassWithArguments>().LifeStyle.Transient.WithParameters((k,
 d) =>
+                       {
+                               d["arg1"] = arg1;
+                               d["arg2"] = arg2;
+                       }));
+                       //Assert.DoesNotThrow(() =>
+                       kernel.Resolve<ClassWithArguments>();//);
+               }
+       }
+
+}

Directory: /InversionOfControl/trunk/src/Castle.MicroKernel/Context/
====================================================================

File [modified]: CreationContext.cs
Delta lines: +24 -2
===================================================================

--- InversionOfControl/trunk/src/Castle.MicroKernel/Handlers/AbstractHandler.cs 
2009-12-10 19:50:49 UTC (rev 6399)
+++ InversionOfControl/trunk/src/Castle.MicroKernel/Handlers/AbstractHandler.cs 
2009-12-10 21:10:17 UTC (rev 6400)
@@ -23,6 +23,8 @@
        using Castle.Core;
        using Castle.MicroKernel.Lifestyle;
 
+       public delegate void ComponentResolvingDelegate(IKernel kernel, 
CreationContext context);
+
        /// <summary>
        /// Implements the basis of <see cref="IHandler"/>
        /// </summary>
@@ -55,6 +57,7 @@
                protected ILifestyleManager lifestyleManager;
 
                private Type service;
+               private ComponentResolvingDelegate resolvingHandler;
 
                /// <summary>
                /// Constructs and initializes the handler
@@ -65,6 +68,9 @@
                        this.model = model;
                        state = HandlerState.Valid;
                        InitializeCustomDependencies();
+                       
if(model.ExtendedProperties.Contains("component_resolving_handler") == false)
+                               return;
+                       resolvingHandler = 
model.ExtendedProperties["component_resolving_handler"] as 
ComponentResolvingDelegate;
                }
 
                #region IHandler Members
@@ -95,10 +101,26 @@
                /// </summary>
                /// <param name="context"></param>
                /// <returns></returns>
-               public abstract object Resolve(CreationContext context);
+               public object Resolve(CreationContext context)
+               {
+                       if(resolvingHandler!=null)
+                       {
+                               resolvingHandler(kernel, context);
+                       }
+                       return ResolveCore(context);
+               }
 
                /// <summary>
                /// Should be implemented by derived classes: 
+               /// returns an instance of the component this handler
+               /// is responsible for
+               /// </summary>
+               /// <param name="context"></param>
+               /// <returns></returns>
+               protected abstract object ResolveCore(CreationContext context);
+
+               /// <summary>
+               /// Should be implemented by derived classes: 
                /// disposes the component instance (or recycle it)
                /// </summary>
                /// <param name="instance"></param>
@@ -679,7 +701,7 @@
 
                        foreach (DictionaryEntry customParameter in 
model.CustomDependencies)
                        {
-                               customParameters.Add(customParameter.Key, 
customParameter.Value);       
+                               customParameters.Add(customParameter.Key, 
customParameter.Value);
                        }
                }

Directory: /InversionOfControl/trunk/src/Castle.MicroKernel/Handlers/
=====================================================================

File [modified]: AbstractHandler.cs
Delta lines: +1 -1
===================================================================

--- 
InversionOfControl/trunk/src/Castle.MicroKernel/Handlers/DefaultGenericHandler.cs
   2009-12-10 19:50:49 UTC (rev 6399)
+++ 
InversionOfControl/trunk/src/Castle.MicroKernel/Handlers/DefaultGenericHandler.cs
   2009-12-10 21:10:17 UTC (rev 6400)
@@ -40,7 +40,7 @@
                        type2SubHandler = new Dictionary<Type, IHandler>();
                }
 
-               public override object Resolve(CreationContext context)
+               protected override object ResolveCore(CreationContext context)
                {
                        Type implType = 
ComponentModel.Implementation.MakeGenericType(context.GenericArguments);

File [modified]: DefaultGenericHandler.cs
Delta lines: +1 -2
===================================================================

--- InversionOfControl/trunk/src/Castle.MicroKernel/Handlers/DefaultHandler.cs  
2009-12-10 19:50:49 UTC (rev 6399)
+++ InversionOfControl/trunk/src/Castle.MicroKernel/Handlers/DefaultHandler.cs  
2009-12-10 21:10:17 UTC (rev 6400)
@@ -20,7 +20,6 @@
 
        using Castle.Core;
        using Castle.MicroKernel.Resolvers;
-       using Castle.MicroKernel.SubSystems.Naming;
 
        /// <summary>
        /// Summary description for DefaultHandler.
@@ -42,7 +41,7 @@
                /// </summary>
                /// <param name="context"></param>
                /// <returns></returns>
-               public override object Resolve(CreationContext context)
+               protected override object ResolveCore(CreationContext context)
                {
                        if (!context.HasAdditionalParameters)

File [modified]: DefaultHandler.cs
Delta lines: +8 -0
===================================================================

--- 
InversionOfControl/trunk/src/Castle.MicroKernel/Registration/ComponentRegistration.cs
       2009-12-10 19:50:49 UTC (rev 6399)
+++ 
InversionOfControl/trunk/src/Castle.MicroKernel/Registration/ComponentRegistration.cs
       2009-12-10 21:10:17 UTC (rev 6400)
@@ -569,6 +569,14 @@
                        this.AddDescriptor(new 
OnCreateComponentDescriptor<S>(actions));
                        return this;
                }
+
+               public ComponentRegistration<S> 
WithParameters(WithParametersDelegate action)
+               {
+
+                       this.AddDescriptor(new 
WithParametersDescriptor<S>(action));
+                       return this;
+               }
+
                /// <summary>
                /// Marks the components with one or more actors.

Directory: /InversionOfControl/trunk/src/Castle.MicroKernel/Registration/
=========================================================================

File [modified]: ComponentRegistration.cs
Delta lines: +50 -0
===================================================================

--- 
InversionOfControl/trunk/src/Castle.MicroKernel/Registration/WithParametersDescriptor.cs
                            (rev 0)
+++ 
InversionOfControl/trunk/src/Castle.MicroKernel/Registration/WithParametersDescriptor.cs
    2009-12-10 21:10:17 UTC (rev 6400)
@@ -0,0 +1,50 @@
+// Copyright 2004-2009 Castle Project - http://www.castleproject.org/
+// 
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+// 
+//     http://www.apache.org/licenses/LICENSE-2.0
+// 
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+namespace Castle.MicroKernel.Registration
+{
+       using System.Collections;
+
+       using Castle.Core;
+       using Castle.MicroKernel.Handlers;
+
+       public delegate void WithParametersDelegate(IKernel kernel, IDictionary 
parameters);
+
+
+       public class WithParametersDescriptor<S> : ComponentDescriptor<S>
+       {
+               private readonly WithParametersDelegate action;
+               private static readonly string key = 
"component_resolving_handler";
+
+               public WithParametersDescriptor(WithParametersDelegate action)
+               {
+                       this.action = action;
+               }
+
+               protected internal override void ApplyToModel(IKernel kernel, 
ComponentModel model)
+               {
+                       ComponentResolvingDelegate handler = (k, c) => 
action(k, c.AdditionalParameters);
+                       if (model.ExtendedProperties.Contains(key) == false)
+                       {
+                               model.ExtendedProperties[key] = handler;
+                               return;
+                       }
+
+                       var @delegate = 
(ComponentResolvingDelegate)model.ExtendedProperties[key];
+                       @delegate += handler;
+
+                       model.ExtendedProperties[key] = @delegate;
+               }
+       }
+}

File [added]: WithParametersDescriptor.cs
Delta lines: +2 -3
===================================================================

--- 
InversionOfControl/trunk/src/Castle.MicroKernel.Tests/Castle.MicroKernel.Tests-vs2008.csproj
        2009-12-10 19:50:49 UTC (rev 6399)
+++ 
InversionOfControl/trunk/src/Castle.MicroKernel.Tests/Castle.MicroKernel.Tests-vs2008.csproj
        2009-12-10 21:10:17 UTC (rev 6400)
@@ -121,6 +121,7 @@
     <Compile 
Include="Bugs\Ioc113\StartableDisposableAndInitializableComponent.cs" />
     <Compile Include="Bugs\IoC_141.cs" />
     <Compile Include="ClassComponents\BaseComponent.cs" />
+    <Compile Include="ClassComponents\ClassWithArguments.cs" />
     <Compile Include="ClassComponents\ClassWithArrayConstructor.cs" />
     <Compile Include="ClassComponents\ClassWithListConstructor.cs">
       <SubType>Code</SubType>
@@ -203,6 +204,7 @@
     <Compile Include="Lifecycle\OnCreateTestCase.cs" />
     <Compile 
Include="Facilities\Startable\Components\StartableChainWithGenerics.cs" />
     <Compile 
Include="Facilities\Startable\Components\StartableComponentWithCustomDependencies.cs"
 />
+    <Compile Include="Registration\WithParametersTestCase.cs" />
     <Compile Include="HandlerForwardingTestCase.cs" />
     <Compile Include="KeySearchNamingSubSystemTestCase.cs" />
     <Compile Include="DefaultConversionManagerTestCase.cs">
@@ -300,9 +302,6 @@
   <ItemGroup>
     <Service Include="{B4F97281-0DBD-4835-9ED8-7DFB966E87FF}" />
   </ItemGroup>
-  <ItemGroup>
-    <Folder Include="Facilities\OnCreate\" />
-  </ItemGroup>
   <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
   <PropertyGroup>

Directory: /InversionOfControl/trunk/src/Castle.MicroKernel.Tests/Registration/
===============================================================================

File [added]: WithParametersTestCase.cs
Delta lines: +5 -0
===================================================================

--- InversionOfControl/trunk/src/Changes.txt    2009-12-10 19:50:49 UTC (rev 
6399)
+++ InversionOfControl/trunk/src/Changes.txt    2009-12-10 21:10:17 UTC (rev 
6400)
@@ -1,3 +1,8 @@
+- added WithParameters method to fluent registration that enables inspecting 
and modifying arguments passed to Resolve method.
+- BREAKING CHANGE - AbstractHandler.Resolve method is no longer abstract and 
instead a ResolveCore protected abstract method was added. To fix this, 
implementers should override ResolveCore instead of Resolve.
+
+- added OnCreate method (refactored from OnCreateFacility created by Tehlike) 
which allows to specify actions to be invoked on the component right after it 
is created, and before it's returned from the container
+
 2.0
 ====

Directory: /InversionOfControl/trunk/src/
=========================================

File [modified]: Changes.txt
Delta lines: +1 -0
===================================================================

--- InversionOfControl/trunk/src/InversionOfControl-vs2008.sln  2009-12-10 
19:50:49 UTC (rev 6399)
+++ InversionOfControl/trunk/src/InversionOfControl-vs2008.sln  2009-12-10 
21:10:17 UTC (rev 6400)
@@ -2,6 +2,7 @@
 # Visual Studio 2008
 Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", 
"Solution Items", "{F9A88F20-64E5-442C-8C20-10C69A39EF4C}"
        ProjectSection(SolutionItems) = preProject
+               Changes.txt = Changes.txt
                License.txt = License.txt
                Readme.txt = Readme.txt

File [modified]: InversionOfControl-vs2008.sln
Delta lines: +0 -0
===================================================================

--

You received this message because you are subscribed to the Google Groups 
"Castle Project Commits" 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/castle-project-commits?hl=en.


Reply via email to