User: xtoff
Date: 2010/01/22 12:14 PM
Added:
/InversionOfControl/trunk/src/Castle.MicroKernel/Facilities/Startable/
StartableFacilityRegistrationExtensions.cs
Modified:
/InversionOfControl/trunk/src/
BreakingChanges.txt, Changes.txt
/InversionOfControl/trunk/src/Castle.MicroKernel.Tests/Registration/
ComponentRegistrationTestCase.cs
/InversionOfControl/trunk/src/Castle.MicroKernel/
Castle.MicroKernel-vs2008.csproj
/InversionOfControl/trunk/src/Castle.MicroKernel/Registration/
ComponentRegistration.cs
Log:
- removed Startable() method from registration API. Moved StartUsingMethod()
and StopUsingMethod() to extension methods in Castle.Facilities.Startable
namespace.
- added strongly typed overloads of StartUsingMethod and StopUsingMethod based
on Expressions.
It is now possible to call .StartUsingMethod(x =>
x.Start).StopUsingMethod(x => x.Stop)
File Changes:
Directory: /InversionOfControl/trunk/src/Castle.MicroKernel/
============================================================
File [modified]: Castle.MicroKernel-vs2008.csproj
Delta lines: +111 -0
===================================================================
---
InversionOfControl/trunk/src/Castle.MicroKernel/Facilities/Startable/StartableFacilityRegistrationExtensions.cs
(rev 0)
+++
InversionOfControl/trunk/src/Castle.MicroKernel/Facilities/Startable/StartableFacilityRegistrationExtensions.cs
2010-01-22 19:14:09 UTC (rev 6710)
@@ -0,0 +1,111 @@
+// Copyright 2004-2010 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.Facilities.Startable
+{
+ using System;
+ using System.Linq.Expressions;
+ using System.Reflection;
+
+ using Castle.MicroKernel.Facilities;
+ using Castle.MicroKernel.Registration;
+
+ public static class StartableFacilityRegistrationExtensions
+ {
+ /// <summary>
+ /// Assigns the start method for the startable.
+ /// </summary>
+ /// <param name="registration"></param>
+ /// <param name="startMethod">The start method.</param>
+ /// <returns></returns>
+ /// <remarks>Be sure that you first added the <see
cref="Castle.Facilities.Startable.StartableFacility"/>
+ /// to the kernel, before registering this component.</remarks>
+ public static ComponentRegistration<TService>
StartUsingMethod<TService>(this ComponentRegistration<TService> registration,
string startMethod)
+ {
+ return SetStartableAttribute(registration)
+ .AddAttributeDescriptor("startMethod",
startMethod);
+ }
+
+ /// <summary>
+ /// Assigns the start method for the startable.
+ /// </summary>
+ /// <param name="registration"></param>
+ /// <param name="methodToUse">Method to use. something like:
StartUsingMethod(s => s.Start)</param>
+ /// <returns></returns>
+ /// <remarks>Be sure that you first added the <see
cref="Castle.Facilities.Startable.StartableFacility"/>
+ /// to the kernel, before registering this component.</remarks>
+ public static ComponentRegistration<TService>
StartUsingMethod<TService>(this ComponentRegistration<TService> registration,
Expression<Func<TService,Action>> methodToUse)
+ {
+ var startMethod = ObtainMethodName(methodToUse);
+ return SetStartableAttribute(registration)
+ .AddAttributeDescriptor("startMethod",
startMethod);
+ }
+
+ /// <summary>
+ /// Assigns the stop method for the startable.
+ /// </summary>
+ /// <param name="registration"></param>
+ /// <param name="stopMethod">The stop method.</param>
+ /// <returns></returns>
+ /// <remarks>Be sure that you first added the <see
cref="Castle.Facilities.Startable.StartableFacility"/>
+ /// to the kernel, before registering this component.</remarks>
+ public static ComponentRegistration<TService>
StopUsingMethod<TService>(this ComponentRegistration<TService> registration,
string stopMethod)
+ {
+ return SetStartableAttribute(registration)
+ .AddAttributeDescriptor("stopMethod",
stopMethod);
+ }
+
+ /// <summary>
+ /// Assigns the stop method for the startable.
+ /// </summary>
+ /// <param name="registration"></param>
+ /// <param name="methodToUse">Method to use. something like:
StartUsingMethod(s => s.Start)</param>
+ /// <returns></returns>
+ /// <remarks>Be sure that you first added the <see
cref="Castle.Facilities.Startable.StartableFacility"/>
+ /// to the kernel, before registering this component.</remarks>
+ public static ComponentRegistration<TService>
StopUsingMethod<TService>(this ComponentRegistration<TService> registration,
Expression<Func<TService, Action>> methodToUse)
+ {
+ var stopMethod = ObtainMethodName(methodToUse);;
+ return SetStartableAttribute(registration)
+ .AddAttributeDescriptor("stopMethod",
stopMethod);
+ }
+
+ private static ComponentRegistration<TService>
SetStartableAttribute<TService>(ComponentRegistration<TService> registration)
+ {
+ return registration.AddAttributeDescriptor("startable",
true.ToString());
+ }
+
+ private static string
ObtainMethodName<TService>(Expression<Func<TService, Action>> methodToUse)
+ {
+ var call = EnsureIs<UnaryExpression>(methodToUse.Body);
+ var createDelegate =
EnsureIs<MethodCallExpression>(call.Operand);
+ var method =
EnsureIs<ConstantExpression>(createDelegate.Arguments[2]);
+
+ return ((MethodInfo)method.Value).Name;
+
+ }
+
+ private static TExpression EnsureIs<TExpression>(Expression
expression) where TExpression : Expression
+ {
+ var casted = expression as TExpression;
+ if (casted == null)
+ {
+ throw new FacilityException(
+ "Unexpected shape of expression.
Expected direct call to method, something like 'x => x.Foo'");
+ }
+
+ return casted;
+ }
+ }
+}
Directory: /InversionOfControl/trunk/src/Castle.MicroKernel/Registration/
=========================================================================
File [modified]: ComponentRegistration.cs
Delta lines: +74 -54
===================================================================
---
InversionOfControl/trunk/src/Castle.MicroKernel.Tests/Registration/ComponentRegistrationTestCase.cs
2010-01-22 16:30:13 UTC (rev 6709)
+++
InversionOfControl/trunk/src/Castle.MicroKernel.Tests/Registration/ComponentRegistrationTestCase.cs
2010-01-22 19:14:09 UTC (rev 6710)
@@ -59,11 +59,11 @@
Assert.AreSame(customer, customer1);
}
- [Test]
- public void
AddComponent_WithInterceptorSelector_ComponentModelShouldHaveInterceptorSelector()
- {
- var selector = new
InterceptorTypeSelector(typeof(TestInterceptor1));
- Kernel.Register(Component.For<ICustomer>().Interceptors(new
InterceptorReference(typeof(TestInterceptor1)))
+ [Test]
+ public void
AddComponent_WithInterceptorSelector_ComponentModelShouldHaveInterceptorSelector()
+ {
+ var selector = new
InterceptorTypeSelector(typeof(TestInterceptor1));
+
Kernel.Register(Component.For<ICustomer>().Interceptors(new
InterceptorReference(typeof(TestInterceptor1)))
.SelectedWith(selector).Anywhere);
IHandler handler = Kernel.GetHandler(typeof(ICustomer));
@@ -71,21 +71,21 @@
var proxyOptions =
ProxyUtil.ObtainProxyOptions(handler.ComponentModel, false);
Assert.IsNotNull(proxyOptions);
- Assert.AreEqual( selector, proxyOptions.Selector.Resolve( null,
null ) );
- }
+ Assert.AreEqual(selector,
proxyOptions.Selector.Resolve(null, null));
+ }
- [Test]
- public void
AddComponent_WithInterfaceServiceOnly_And_Interceptors_ProxyOptionsShouldNotHaveATarget()
- {
- Kernel.Register(Component.For<ICustomer>().Interceptors(new
InterceptorReference(typeof(StandardInterceptor))).Anywhere);
+ [Test]
+ public void
AddComponent_WithInterfaceServiceOnly_And_Interceptors_ProxyOptionsShouldNotHaveATarget()
+ {
+
Kernel.Register(Component.For<ICustomer>().Interceptors(new
InterceptorReference(typeof(StandardInterceptor))).Anywhere);
- IHandler handler = Kernel.GetHandler(typeof(ICustomer));
+ IHandler handler = Kernel.GetHandler(typeof(ICustomer));
- var proxyOptions =
ProxyUtil.ObtainProxyOptions(handler.ComponentModel, false);
+ var proxyOptions =
ProxyUtil.ObtainProxyOptions(handler.ComponentModel, false);
- Assert.IsNotNull(proxyOptions);
- Assert.IsTrue(proxyOptions.OmitTarget);
- }
+ Assert.IsNotNull(proxyOptions);
+ Assert.IsTrue(proxyOptions.OmitTarget);
+ }
[Test]
public void AddComponent_WithServiceAndName_RegisteredNamed()
@@ -100,7 +100,7 @@
Assert.AreEqual(typeof(CustomerImpl),
handler.ComponentModel.Service);
Assert.AreEqual(typeof(CustomerImpl),
handler.ComponentModel.Implementation);
- CustomerImpl customer = (CustomerImpl)
Kernel["customer"];
+ CustomerImpl customer =
(CustomerImpl)Kernel["customer"];
Assert.IsNotNull(customer);
}
@@ -179,7 +179,7 @@
[Test]
public void AddComponent_Instance_UsesInstanceWithParameters()
{
- CustomerImpl2 customer = new
CustomerImpl2("ernst","delft", 29);
+ CustomerImpl2 customer = new CustomerImpl2("ernst",
"delft", 29);
Kernel.Register(
Component.For<ICustomer>()
@@ -266,7 +266,7 @@
IHandler handler = Kernel.GetHandler("customer");
Assert.AreEqual(LifestyleType.Thread,
handler.ComponentModel.LifestyleType);
}
-
+
#if (!SILVERLIGHT)
[Test]
public void AddComponent_WithPerWebRequestLifestyle_WorksFine()
@@ -380,10 +380,10 @@
[Test]
public void AddComponent_CustomDependencies_UsingAnonymousType()
{
- Kernel.Register(
- Component.For<ICustomer>()
- .ImplementedBy<CustomerImpl>()
- .DependsOn(new { Name = "Caption Hook",
Address = "Fairyland", Age = 45 }));
+ Kernel.Register(
+ Component.For<ICustomer>()
+ .ImplementedBy<CustomerImpl>()
+ .DependsOn(new { Name = "Caption Hook", Address
= "Fairyland", Age = 45 }));
ICustomer customer = Kernel.Resolve<ICustomer>();
Assert.AreEqual(customer.Name, "Caption Hook");
@@ -435,7 +435,7 @@
)
);
- CustomerChain1 customer = (CustomerChain1)
Kernel["customer2"];
+ CustomerChain1 customer =
(CustomerChain1)Kernel["customer2"];
Assert.IsNotNull(customer.CustomerBase);
Assert.AreEqual(customer.CustomerBase.Name, "Caption
Hook");
Assert.AreEqual(customer.CustomerBase.Address,
"Fairyland");
@@ -459,8 +459,8 @@
)
);
- ICommon common1 = (ICommon) Kernel["common1"];
- ICommon common2 = (ICommon) Kernel["common2"];
+ ICommon common1 = (ICommon)Kernel["common1"];
+ ICommon common2 = (ICommon)Kernel["common2"];
ClassWithArrayConstructor component =
Kernel.Resolve<ClassWithArrayConstructor>();
Assert.AreSame(common2, component.First);
Assert.AreEqual(2, component.Services.Length);
@@ -514,7 +514,7 @@
.ServiceOverrides(new { customer =
"customer1" })
);
- CustomerChain1 customer = (CustomerChain1)
Kernel["customer2"];
+ CustomerChain1 customer =
(CustomerChain1)Kernel["customer2"];
Assert.IsNotNull(customer.CustomerBase);
Assert.AreEqual(customer.CustomerBase.Name, "Caption
Hook");
Assert.AreEqual(customer.CustomerBase.Address,
"Fairyland");
@@ -545,7 +545,7 @@
.ServiceOverrides(serviceOverrides)
);
- CustomerChain1 customer = (CustomerChain1)
Kernel["customer2"];
+ CustomerChain1 customer =
(CustomerChain1)Kernel["customer2"];
Assert.IsNotNull(customer.CustomerBase);
Assert.AreEqual(customer.CustomerBase.Name, "Caption
Hook");
Assert.AreEqual(customer.CustomerBase.Address,
"Fairyland");
@@ -634,9 +634,9 @@
Assert.IsNotNull(component);
Assert.IsNotNull(component.ComplexParam);
Assert.AreEqual("value1",
component.ComplexParam.MandatoryValue);
- Assert.AreEqual("value2",
component.ComplexParam.OptionalValue);
+ Assert.AreEqual("value2",
component.ComplexParam.OptionalValue);
}
-
+
[Test]
public void
CanUseExistingComponentModelWithComponentRegistration()
{
@@ -647,7 +647,7 @@
IHandler handler = Kernel.GetHandler(typeof(ICustomer));
ComponentRegistration component =
Component.For(handler.ComponentModel);
- Assert.AreEqual(typeof(ICustomer),
component.ServiceType);
+ Assert.AreEqual(typeof(ICustomer),
component.ServiceType);
Assert.AreEqual(typeof(CustomerImpl),
component.Implementation);
}
@@ -701,7 +701,7 @@
Kernel.AddFacility<StartableFacility>()
.Register(Component.For<StartableComponent>());
- StartableComponent component =
Kernel.Resolve<StartableComponent>();
+ var component = Kernel.Resolve<StartableComponent>();
Assert.IsNotNull(component);
Assert.IsTrue(component.Started);
@@ -720,7 +720,7 @@
.StopUsingMethod("Stop")
);
- NoInterfaceStartableComponent component =
Kernel.Resolve<NoInterfaceStartableComponent>();
+ var component =
Kernel.Resolve<NoInterfaceStartableComponent>();
Assert.IsNotNull(component);
Assert.IsTrue(component.Started);
@@ -729,28 +729,48 @@
Kernel.ReleaseComponent(component);
Assert.IsTrue(component.Stopped);
}
+
+ [Test]
+ public void
AddComponent_StartableWithoutInterface_StartsComponent_via_expression()
+ {
+ Kernel.AddFacility<StartableFacility>()
+
.Register(Component.For<NoInterfaceStartableComponent>()
+ .StartUsingMethod(x =>
x.Start)
+ .StopUsingMethod(x =>
x.Stop)
+ );
+
+ var component =
Kernel.Resolve<NoInterfaceStartableComponent>();
+
+ Assert.IsNotNull(component);
+ Assert.IsTrue(component.Started);
+ Assert.IsFalse(component.Stopped);
+
+ Kernel.ReleaseComponent(component);
+ Assert.IsTrue(component.Stopped);
+ }
}
- public class InterceptorTypeSelector : IInterceptorSelector
- {
- private readonly Type interceptorType;
+ public class InterceptorTypeSelector : IInterceptorSelector
+ {
+ private readonly Type interceptorType;
- public InterceptorTypeSelector(Type interceptorType)
- {
- this.interceptorType = interceptorType;
- }
+ public InterceptorTypeSelector(Type interceptorType)
+ {
+ this.interceptorType = interceptorType;
+ }
- public IInterceptor[] SelectInterceptors(Type type, MethodInfo method,
IInterceptor[] interceptors)
- {
- return interceptors.Where(i => i.GetType() ==
interceptorType).ToArray();
- }
- }
+ public IInterceptor[] SelectInterceptors(Type type, MethodInfo
method, IInterceptor[] interceptors)
+ {
+ return interceptors.Where(i => i.GetType() ==
interceptorType).ToArray();
+ }
+ }
public abstract class TestInterceptor : IInterceptor
{
public int Invocations
{
- get; set;
+ get;
+ set;
}
public void Intercept(IInvocation invocation)
@@ -761,14 +781,14 @@
}
public class TestInterceptor1 : TestInterceptor
- {
- }
+ {
+ }
- public class TestInterceptor2 : TestInterceptor
- {
- }
+ public class TestInterceptor2 : TestInterceptor
+ {
+ }
- public class TestInterceptor3 : TestInterceptor
- {
- }
+ public class TestInterceptor3 : TestInterceptor
+ {
+ }
}
Directory: /InversionOfControl/trunk/src/Castle.MicroKernel.Tests/Registration/
===============================================================================
File [modified]: ComponentRegistrationTestCase.cs
Delta lines: +7 -0
===================================================================
--- InversionOfControl/trunk/src/Changes.txt 2010-01-22 16:30:13 UTC (rev
6709)
+++ InversionOfControl/trunk/src/Changes.txt 2010-01-22 19:14:09 UTC (rev
6710)
@@ -1,5 +1,12 @@
unreleased changes
==================
+
+- added strongly typed overloads for StartUsingMethod and StopUsingMethod from
startable facility's registration API. It is now possible to call
.StartUsingMethod(x => x.Start).StopUsingMethod(x => x.Stop)
+
+- moved StartUsingMethod/StopUsingMethod to extension methods in
StartableFacility's namespace. Startable() method was removed as superfluous.
+
+- changed the UsingFactoryMethod (and UsingFactory) methods in fluent
registration API to not rely on FactorySupportFacility. They now work even if
facility is not used.
+
- fixed IOC-ISSUE-190 - "Resolve with argumentsAsAnonymousType overload is now
case sensitive".
This fixed a regression bug introduced in v2.1, and brings the behavior
back to what it was in v2.0.
Directory:
/InversionOfControl/trunk/src/Castle.MicroKernel/Facilities/Startable/
=================================================================================
File [added]: StartableFacilityRegistrationExtensions.cs
Delta lines: +0 -36
===================================================================
---
InversionOfControl/trunk/src/Castle.MicroKernel/Registration/ComponentRegistration.cs
2010-01-22 16:30:13 UTC (rev 6709)
+++
InversionOfControl/trunk/src/Castle.MicroKernel/Registration/ComponentRegistration.cs
2010-01-22 19:14:09 UTC (rev 6710)
@@ -561,44 +561,8 @@
return AddDescriptor(new
Interceptor.InterceptorSelectorDescriptor<S>(selector));
}
- /// <summary>
- /// Marks the component as startable.
- /// </summary>
- /// <returns></returns>
- /// <remarks>Be sure that you first added the <see
cref="Castle.Facilities.Startable.StartableFacility"/>
- /// to the kernel, before registering this component.</remarks>
- public ComponentRegistration<S> Startable()
- {
- return AddAttributeDescriptor("startable", "true");
- }
/// <summary>
- /// Assigns the start method for the startable.
- /// </summary>
- /// <param name="startMethod">The start method.</param>
- /// <returns></returns>
- /// <remarks>Be sure that you first added the <see
cref="Castle.Facilities.Startable.StartableFacility"/>
- /// to the kernel, before registering this component.</remarks>
- public ComponentRegistration<S> StartUsingMethod(string
startMethod)
- {
- return Startable()
- .AddAttributeDescriptor("startMethod",
startMethod);
- }
-
- /// <summary>
- /// Assigns the stop method for the startable.
- /// </summary>
- /// <param name="stopMethod">The stop method.</param>
- /// <returns></returns>
- /// <remarks>Be sure that you first added the <see
cref="Castle.Facilities.Startable.StartableFacility"/>
- /// to the kernel, before registering this component.</remarks>
- public ComponentRegistration<S> StopUsingMethod(string
stopMethod)
- {
- return Startable()
- .AddAttributeDescriptor("stopMethod",
stopMethod);
- }
-
- /// <summary>
/// Stores a set of <see cref="OnCreateActionDelegate{T}"/>
which will be invoked when the component
/// is created and before it's returned from the container.
Directory: /InversionOfControl/trunk/src/
=========================================
File [modified]: BreakingChanges.txt
Delta lines: +1 -0
===================================================================
---
InversionOfControl/trunk/src/Castle.MicroKernel/Castle.MicroKernel-vs2008.csproj
2010-01-22 16:30:13 UTC (rev 6709)
+++
InversionOfControl/trunk/src/Castle.MicroKernel/Castle.MicroKernel-vs2008.csproj
2010-01-22 19:14:09 UTC (rev 6710)
@@ -176,6 +176,7 @@
<Compile Include="Facilities\Startable\StartableFacility.cs">
<SubType>Code</SubType>
</Compile>
+ <Compile
Include="Facilities\Startable\StartableFacilityRegistrationExtensions.cs" />
<Compile Include="Facilities\Startable\StartConcern.cs">
<SubType>Code</SubType>
File [modified]: Changes.txt
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.