User: xtoff
Date: 2010/01/01 09:36 AM
Added:
/InversionOfControl/trunk/src/Castle.MicroKernel.Tests/ClassComponents/
HasTwoConstructors.cs, HasTwoConstructors2.cs, ServiceUser.cs, ServiceUser2.cs
Modified:
/InversionOfControl/trunk/src/Castle.MicroKernel.Tests/
BestConstructorTestCase.cs, Castle.MicroKernel.Tests-vs2008.csproj
/InversionOfControl/trunk/src/Castle.MicroKernel/Handlers/
AbstractHandler.cs
Log:
- fixed IOC-ISSUE-168 - When there are multiple greediest .ctors behavior is
undefined. Partially based on patch by Mauricio.
- this patch changes (and defines more precisely) behavior when there are
multiple satisfiable constructors with biggest equal number of parameters
in this case:
- one with greatest number of explicitly defined dependencies (meaning
parameter dependencies or service override dependencies) is picked
- if there's more than one, from candidates selected in previous step,
corresponding parameter names are compared in order, until one with "smallest"
name is found.
- if there's more than one, from candidates selected in previous step, it is
undefined which one is selected.
File Changes:
Directory: /InversionOfControl/trunk/src/Castle.MicroKernel.Tests/
==================================================================
File [modified]: BestConstructorTestCase.cs
Delta lines: +4 -0
===================================================================
---
InversionOfControl/trunk/src/Castle.MicroKernel.Tests/Castle.MicroKernel.Tests-vs2008.csproj
2009-12-31 23:29:57 UTC (rev 6550)
+++
InversionOfControl/trunk/src/Castle.MicroKernel.Tests/Castle.MicroKernel.Tests-vs2008.csproj
2010-01-01 16:36:07 UTC (rev 6551)
@@ -145,6 +145,8 @@
<SubType>Code</SubType>
</Compile>
<Compile Include="ClassComponents\CommonImplWithDependancy.cs" />
+ <Compile Include="ClassComponents\HasTwoConstructors.cs" />
+ <Compile Include="ClassComponents\HasTwoConstructors2.cs" />
<Compile Include="ClassComponents\ICommon2.cs" />
<Compile Include="ClassComponents\IMapper.cs" />
<Compile Include="ClassComponents\ICommonSub1.cs" />
@@ -189,6 +191,8 @@
<SubType>Code</SubType>
</Compile>
<Compile Include="ClassComponents\Repository.cs" />
+ <Compile Include="ClassComponents\ServiceUser.cs" />
+ <Compile Include="ClassComponents\ServiceUser2.cs" />
<Compile Include="ClassComponents\TwoInterfacesImpl.cs" />
<Compile Include="Configuration\Components\ClassWithComplexParameter.cs" />
File [modified]: Castle.MicroKernel.Tests-vs2008.csproj
Delta lines: +32 -0
===================================================================
---
InversionOfControl/trunk/src/Castle.MicroKernel.Tests/ClassComponents/HasTwoConstructors.cs
(rev 0)
+++
InversionOfControl/trunk/src/Castle.MicroKernel.Tests/ClassComponents/HasTwoConstructors.cs
2010-01-01 16:36:07 UTC (rev 6551)
@@ -0,0 +1,32 @@
+// 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 HasTwoConstructors
+ {
+ public ICommon Common { get; set; }
+ public ICustomer Customer { get; set; }
+
+ public HasTwoConstructors(ICustomer customer)
+ {
+ Customer = customer;
+ }
+
+ public HasTwoConstructors(ICommon common)
+ {
+ Common = common;
+ }
+ }
+}
Directory:
/InversionOfControl/trunk/src/Castle.MicroKernel.Tests/ClassComponents/
==================================================================================
File [added]: HasTwoConstructors.cs
Delta lines: +32 -0
===================================================================
---
InversionOfControl/trunk/src/Castle.MicroKernel.Tests/ClassComponents/HasTwoConstructors2.cs
(rev 0)
+++
InversionOfControl/trunk/src/Castle.MicroKernel.Tests/ClassComponents/HasTwoConstructors2.cs
2010-01-01 16:36:07 UTC (rev 6551)
@@ -0,0 +1,32 @@
+// 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 HasTwoConstructors2
+ {
+ public string Param { get; set; }
+ public ICommon Common { get; set; }
+
+ public HasTwoConstructors2(ICommon common)
+ {
+ Common = common;
+ }
+
+ public HasTwoConstructors2(string param)
+ {
+ Param = param;
+ }
+ }
+}
File [added]: HasTwoConstructors2.cs
Delta lines: +58 -0
===================================================================
---
InversionOfControl/trunk/src/Castle.MicroKernel.Tests/ClassComponents/ServiceUser.cs
(rev 0)
+++
InversionOfControl/trunk/src/Castle.MicroKernel.Tests/ClassComponents/ServiceUser.cs
2010-01-01 16:36:07 UTC (rev 6551)
@@ -0,0 +1,58 @@
+// 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
+{
+ using System;
+
+ public class ServiceUser
+ {
+ private A _a;
+ private B _b;
+ private C _c;
+
+ public ServiceUser(A a)
+ {
+ if (a == null) throw new ArgumentNullException();
+ _a = a;
+ }
+
+ public ServiceUser(A a, B b) : this(a)
+ {
+ if (b == null) throw new ArgumentNullException();
+ _b = b;
+ }
+
+ public ServiceUser(A a, B b, C c) : this(a, b)
+ {
+ if (c == null) throw new ArgumentNullException();
+ _c = c;
+ }
+
+ public A AComponent
+ {
+ get { return _a; }
+ }
+
+ public B BComponent
+ {
+ get { return _b; }
+ }
+
+ public C CComponent
+ {
+ get { return _c; }
+ }
+ }
+}
File [added]: ServiceUser.cs
Delta lines: +51 -0
===================================================================
---
InversionOfControl/trunk/src/Castle.MicroKernel.Tests/ClassComponents/ServiceUser2.cs
(rev 0)
+++
InversionOfControl/trunk/src/Castle.MicroKernel.Tests/ClassComponents/ServiceUser2.cs
2010-01-01 16:36:07 UTC (rev 6551)
@@ -0,0 +1,51 @@
+// 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
+{
+ using System;
+
+ public class ServiceUser2 : ServiceUser
+ {
+ private string _name;
+ private int _port;
+ private int _scheduleinterval;
+
+ public ServiceUser2(A a, String name, int port) : base(a)
+ {
+ _name = name;
+ _port = port;
+ }
+
+ public ServiceUser2(A a, String name, int port, int
scheduleinterval) : this(a, name, port)
+ {
+ _scheduleinterval = scheduleinterval;
+ }
+
+ public String Name
+ {
+ get { return _name; }
+ }
+
+ public int Port
+ {
+ get { return _port; }
+ }
+
+ public int ScheduleInterval
+ {
+ get { return _scheduleinterval; }
+ }
+ }
+}
File [added]: ServiceUser2.cs
Delta lines: +0 -0
===================================================================
Directory: /InversionOfControl/trunk/src/Castle.MicroKernel/Handlers/
=====================================================================
File [modified]: AbstractHandler.cs
Delta lines: +55 -74
===================================================================
---
InversionOfControl/trunk/src/Castle.MicroKernel.Tests/BestConstructorTestCase.cs
2009-12-31 23:29:57 UTC (rev 6550)
+++
InversionOfControl/trunk/src/Castle.MicroKernel.Tests/BestConstructorTestCase.cs
2010-01-01 16:36:07 UTC (rev 6551)
@@ -14,84 +14,13 @@
namespace Castle.MicroKernel.Tests
{
- using System;
using Castle.Core.Configuration;
+ using Castle.MicroKernel.Registration;
using Castle.MicroKernel.SubSystems.Configuration;
+ using Castle.MicroKernel.Tests.ClassComponents;
+
using NUnit.Framework;
- public class ServiceUser
- {
- private A _a;
- private B _b;
- private C _c;
-
- public ServiceUser(A a)
- {
- if (a == null) throw new ArgumentNullException();
- _a = a;
- }
-
- public ServiceUser(A a, B b) : this(a)
- {
- if (b == null) throw new ArgumentNullException();
- _b = b;
- }
-
- public ServiceUser(A a, B b, C c) : this(a, b)
- {
- if (c == null) throw new ArgumentNullException();
- _c = c;
- }
-
- public A AComponent
- {
- get { return _a; }
- }
-
- public B BComponent
- {
- get { return _b; }
- }
-
- public C CComponent
- {
- get { return _c; }
- }
- }
-
- public class ServiceUser2 : ServiceUser
- {
- private string _name;
- private int _port;
- private int _scheduleinterval;
-
- public ServiceUser2(A a, String name, int port) : base(a)
- {
- _name = name;
- _port = port;
- }
-
- public ServiceUser2(A a, String name, int port, int
scheduleinterval) : this(a, name, port)
- {
- _scheduleinterval = scheduleinterval;
- }
-
- public String Name
- {
- get { return _name; }
- }
-
- public int Port
- {
- get { return _port; }
- }
-
- public int ScheduleInterval
- {
- get { return _scheduleinterval; }
- }
- }
-
/// <summary>
/// Summary description for BestConstructorTestCase.
/// </summary>
@@ -214,5 +143,57 @@
Assert.AreEqual(120, service.Port);
Assert.AreEqual(22, service.ScheduleInterval);
}
+
+ [Test]
+ public void
Two_constructors_equal_number_of_parameters_pick_one_that_can_be_satisfied()
+ {
+
kernel.Register(Component.For<ICommon>().ImplementedBy<CommonImpl1>(),
+ Component.For<HasTwoConstructors>());
+
+ kernel.Resolve<HasTwoConstructors>();
+ }
+
+ [Test]
+ public void
Two_satisfiable_constructors_pick_one_with_more_inline_parameters()
+ {
+
kernel.Register(Component.For<ICommon>().ImplementedBy<CommonImpl1>(),
+ Component.For<HasTwoConstructors2>()
+
.Parameters(Parameter.ForKey("param").Eq("foo")));
+
+ var component = kernel.Resolve<HasTwoConstructors2>();
+
+ Assert.AreEqual("foo", component.Param);
+ }
+
+ [Test]
+ public void
Two_satisfiable_constructors_equal_number_of_inline_parameters_pick_one_with_more_service_overrides()
+ {
+
kernel.Register(Component.For<ICommon>().ImplementedBy<CommonImpl1>().Named("Mucha"),
+
Component.For<ICustomer>().ImplementedBy<CustomerImpl>().Named("Stefan"),
+
Component.For<HasTwoConstructors>().Named("first")
+ .ServiceOverrides(new {
customer = "Stefan" }),
+
Component.For<HasTwoConstructors>().Named("second")
+ .ServiceOverrides(new { common
= "Mucha" }));
+
+ var first = kernel.Resolve<HasTwoConstructors>("first");
+ var second =
kernel.Resolve<HasTwoConstructors>("second");
+
+ Assert.IsNotNull(first.Customer);
+ Assert.IsNotNull(second.Common);
+ }
+
+ [Test]
+ public void
Two_satisfiable_constructors_identical_dependency_kinds_pick_based_on_parameter_names()
+ {
+
kernel.Register(Component.For<ICommon>().ImplementedBy<CommonImpl1>(),
+
Component.For<ICustomer>().ImplementedBy<CustomerImpl>(),
+ Component.For<HasTwoConstructors>());
+
+ var component = kernel.Resolve<HasTwoConstructors>();
+
+ // common is 'smaller' so we pick ctor with dependency
named 'common'
+ Assert.Less("common", "customer");
+ Assert.IsNotNull(component.Common);
+ }
}
}
--
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.