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.