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.

Reply via email to