User: xtoff
Date: 2010/01/07 03:12 PM

Modified:
 
/InversionOfControl/trunk/src/Castle.MicroKernel.Tests/Facilities/FactorySupport/
  FactorySupportFluentTestCase.cs, FactorySupportProgrammaticTestCase.cs, 
FactorySupportTestCase.cs
 /InversionOfControl/trunk/src/Castle.MicroKernel/Facilities/FactorySupport/
  AccessorActivator.cs, FactoryActivator.cs, FactorySupportFacility.cs

Log:
 - BREAKING CHANGE - factory support facility no longer registers factory type 
as implementation of its components - uses the service as implementation.
 - factory facility now checks if returned type is compatibile with registered 
factory type and throws (with pretty descriptive message) otherwise.
 - that's part of the work to improve situation described in IOC-ISSUE-153

File Changes:

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

File [modified]: AccessorActivator.cs
Delta lines: +30 -16
===================================================================

--- 
InversionOfControl/trunk/src/Castle.MicroKernel/Facilities/FactorySupport/FactoryActivator.cs
       2010-01-07 21:36:56 UTC (rev 6594)
+++ 
InversionOfControl/trunk/src/Castle.MicroKernel/Facilities/FactorySupport/FactoryActivator.cs
       2010-01-07 22:12:54 UTC (rev 6595)
@@ -60,9 +60,12 @@
                                factoryType.GetMethod(factoryCreate,
                                        BindingFlags.Public | 
BindingFlags.Static);
 
+                       object instance;
+                       string createMethodName;
                        if (staticCreateMethod != null)
                        {
-                               return Create(null, factoryId, 
staticCreateMethod, factoryCreate, context);
+                               createMethodName = 
staticCreateMethod.ToString();
+                               instance = this.Create(null, factoryId, 
staticCreateMethod, factoryCreate, context);
                        }
                        else
                        {
@@ -81,20 +84,31 @@
                                                        BindingFlags.Public | 
BindingFlags.Instance);
                                }
 
-                               if (instanceCreateMethod != null)
+                               if (instanceCreateMethod == null)
                                {
-                                       return Create(factoryInstance, 
factoryId, instanceCreateMethod, factoryCreate, context);
-                               }
-                               else
-                               {
                                        String message = String.Format("You 
have specified a factory " +
-                                                                      "('{2}' 
- method to be called: {3}) " +
-                                                                      "for the 
component '{0}' {1} but we couldn't find the creation method" +
-                                                                      
"(neither instance or static method with the name '{3}')",
-                                                                      
Model.Name, Model.Implementation.FullName, factoryId, factoryCreate);
+                                                                               
                        "('{2}' - method to be called: {3}) " +
+                                                                               
                        "for the component '{0}' {1} but we couldn't find the 
creation method" +
+                                                                               
                        "(neither instance or static method with the name 
'{3}')",
+                                                                               
                        this.Model.Name, this.Model.Implementation.FullName, 
factoryId, factoryCreate);
                                        throw new FacilityException(message);
                                }
+
+                               createMethodName = 
instanceCreateMethod.ToString();
+                               instance = this.Create(factoryInstance, 
factoryId, instanceCreateMethod, factoryCreate, context);
                        }
+                       var type = 
context.Handler.ComponentModel.Implementation;
+                       if (instance != null && type != null && 
type.IsInstanceOfType(instance) == false)
+                       {
+                               String message =
+                                       String.Format(
+                                               "Factory '{0}' (method '{1}') 
created instance of type {2}.{5}" +
+                                               "This type is not compatible 
with implementation type {3} registered for this component ({4}).{5}" +
+                                               "This may signify a bug. If 
it's the expected behavior, change the registration of this component to cover 
this return type.",
+                                               factoryId, createMethodName, 
instance.GetType().FullName, type.FullName, 
context.Handler.ComponentModel.Name, Environment.NewLine);
+                               throw new FacilityException(message);
+                       }
+                       return instance;
                }
 
                private object Create(object factoryInstance, string factoryId, 
MethodInfo instanceCreateMethod, string factoryCreate, CreationContext context)
@@ -110,7 +124,7 @@
                                ParameterInfo[] parameters = 
instanceCreateMethod.GetParameters();
 
 
-                               foreach(ParameterInfo parameter in parameters)
+                               foreach (ParameterInfo parameter in parameters)
                                {
                                        Type paramType = 
parameter.ParameterType;
 
@@ -167,13 +181,13 @@
                                {
                                        instance = 
Kernel.ProxyFactory.Create(Kernel, instance, Model, context, 
methodArgs.ToArray());
                                }
-                               catch ( Exception ex )
+                               catch (Exception ex)
                                {
-                                       throw new ComponentActivatorException( 
"FactoryActivator: could not proxy " +
-                                                instance.GetType().FullName, 
ex );
+                                       throw new 
ComponentActivatorException("FactoryActivator: could not proxy " +
+                                                instance.GetType().FullName, 
ex);
                                }
-                       }       
-                       
+                       }
+
                        return instance;
                }

File [modified]: FactoryActivator.cs
Delta lines: +4 -10
===================================================================

--- 
InversionOfControl/trunk/src/Castle.MicroKernel/Facilities/FactorySupport/FactorySupportFacility.cs
 2010-01-07 21:36:56 UTC (rev 6594)
+++ 
InversionOfControl/trunk/src/Castle.MicroKernel/Facilities/FactorySupport/FactorySupportFacility.cs
 2010-01-07 22:12:54 UTC (rev 6595)
@@ -91,9 +91,8 @@
                public void AddFactory<TService, TFactory>(
                        string serviceKey, string factoryCreateMethodName, 
string factoryId)
                {
-                       IConfiguration cfg = new 
MutableConfiguration(serviceKey);
+                       var cfg = new MutableConfiguration(serviceKey);
                        cfg.Attributes["factoryCreate"] = 
factoryCreateMethodName;
-
                        AddFactoryComponent<TService, TFactory>(cfg, factoryId, 
serviceKey);
                }
 
@@ -102,19 +101,14 @@
                private void AddFactoryComponent<TService, TFactory>(
                        IConfiguration cfg, string factoryId, string serviceKey)
                {
-                       Type factoryType = typeof(TFactory);
-                       Type serviceType = typeof(TService);
+                       var factoryType = typeof(TFactory);
+                       var serviceType = typeof(TService);
 
                        EnsureFactoryIsRegistered(factoryId, factoryType);
 
-                       ComponentModel serviceModel = 
Kernel.ComponentModelBuilder.BuildModel(
-                               serviceKey, serviceType,
-                               factoryType, null);
-
+                       var serviceModel = 
Kernel.ComponentModelBuilder.BuildModel(serviceKey, serviceType, serviceType, 
null);
                        cfg.Attributes["factoryId"] = factoryId;
-
                        serviceModel.Configuration = cfg;
-
                        Kernel.AddCustomComponent(serviceModel);
                }

File [modified]: FactorySupportFacility.cs
Delta lines: +64 -65
===================================================================

--- 
InversionOfControl/trunk/src/Castle.MicroKernel.Tests/Facilities/FactorySupport/FactorySupportFluentTestCase.cs
     2010-01-07 21:36:56 UTC (rev 6594)
+++ 
InversionOfControl/trunk/src/Castle.MicroKernel.Tests/Facilities/FactorySupport/FactorySupportFluentTestCase.cs
     2010-01-07 22:12:54 UTC (rev 6595)
@@ -59,7 +59,7 @@
                [Test]
                public void register_ferrari_implementation_get_honda_instance()
                {
-                       RegisterComponentsImplemtedByFerrari(new User() { 
FiscalStability = FiscalStability.DirtFarmer });
+                       RegisterComponentsImplemtedByFerrari(new User { 
FiscalStability = FiscalStability.DirtFarmer });
                        Assert.IsInstanceOf(typeof(HondaProvider), 
kernel.Resolve<ICarProvider>());
                }
 
@@ -83,81 +83,80 @@
                                
Component.For<User>().Named("currentUser").Instance(user),
                                
Component.For<AbstractCarProviderFactory>().Named("AbstractCarProviderFactory"),
                                Component.For<ICarProvider>()
-                                       .ImplementedBy<FerrariProvider>()
                                        
.Attribute("factoryId").Eq("AbstractCarProviderFactory")
                                        .Attribute("factoryCreate").Eq("Create")
                                );
                }
 
-        [Test]
-        public void RegisterWithFluentFactory() 
-        {
-            var user = new User {FiscalStability = FiscalStability.DirtFarmer};
-            kernel.Register(
-                Component.For<User>().Instance(user),
-                Component.For<AbstractCarProviderFactory>(),
-                Component.For<ICarProvider>()
-                    .UsingFactory((AbstractCarProviderFactory f) => 
f.Create(kernel.Resolve<User>()))
-                );
-            Assert.IsInstanceOf(typeof(HondaProvider), 
kernel.Resolve<ICarProvider>());
-        }
+               [Test]
+               public void RegisterWithFluentFactory()
+               {
+                       var user = new User { FiscalStability = 
FiscalStability.DirtFarmer };
+                       kernel.Register(
+                               Component.For<User>().Instance(user),
+                               Component.For<AbstractCarProviderFactory>(),
+                               Component.For<ICarProvider>()
+                                       
.UsingFactory((AbstractCarProviderFactory f) => 
f.Create(kernel.Resolve<User>()))
+                               );
+                       Assert.IsInstanceOf(typeof(HondaProvider), 
kernel.Resolve<ICarProvider>());
+               }
 
-        [Test]
-        public void RegisterWithFactoryMethod() 
-        {
-            var user = new User { FiscalStability = FiscalStability.DirtFarmer 
};
-            kernel.Register(
-                Component.For<AbstractCarProviderFactory>(),
-                Component.For<ICarProvider>()
-                    .UsingFactoryMethod(() => new 
AbstractCarProviderFactory().Create(user))
-                );
-            Assert.IsInstanceOf(typeof(HondaProvider), 
kernel.Resolve<ICarProvider>());
-        }
+               [Test]
+               public void RegisterWithFactoryMethod()
+               {
+                       var user = new User { FiscalStability = 
FiscalStability.DirtFarmer };
+                       kernel.Register(
+                               Component.For<AbstractCarProviderFactory>(),
+                               Component.For<ICarProvider>()
+                                       .UsingFactoryMethod(() => new 
AbstractCarProviderFactory().Create(user))
+                               );
+                       Assert.IsInstanceOf(typeof(HondaProvider), 
kernel.Resolve<ICarProvider>());
+               }
 
-        [Test]
-        public void RegisterWithFactoryMethodAndKernel() 
-        {
-            var user = new User { FiscalStability = 
FiscalStability.MrMoneyBags };
-            kernel.Register(
-                Component.For<User>().Instance(user),
-                Component.For<AbstractCarProviderFactory>(),
-                Component.For<ICarProvider>()
-                    .UsingFactoryMethod(k => new 
AbstractCarProviderFactory().Create(k.Resolve<User>()))
-                );
-            Assert.IsInstanceOf(typeof(FerrariProvider), 
kernel.Resolve<ICarProvider>());
-        }
+               [Test]
+               public void RegisterWithFactoryMethodAndKernel()
+               {
+                       var user = new User { FiscalStability = 
FiscalStability.MrMoneyBags };
+                       kernel.Register(
+                               Component.For<User>().Instance(user),
+                               Component.For<AbstractCarProviderFactory>(),
+                               Component.For<ICarProvider>()
+                                       .UsingFactoryMethod(k => new 
AbstractCarProviderFactory().Create(k.Resolve<User>()))
+                               );
+                       Assert.IsInstanceOf(typeof(FerrariProvider), 
kernel.Resolve<ICarProvider>());
+               }
 
-        [Test]
-        public void RegisterWithFactoryMethodNamed()
-        {
-            kernel.Register(
-                Component.For<ICarProvider>()
-                    .UsingFactoryMethod(() => new 
AbstractCarProviderFactory().Create(new User { FiscalStability = 
FiscalStability.MrMoneyBags }))
-                    .Named("ferrariProvider"),
-                Component.For<ICarProvider>()
-                    .UsingFactoryMethod(() => new 
AbstractCarProviderFactory().Create(new User { FiscalStability = 
FiscalStability.DirtFarmer }))
-                    .Named("hondaProvider")
-                );
+               [Test]
+               public void RegisterWithFactoryMethodNamed()
+               {
+                       kernel.Register(
+                               Component.For<ICarProvider>()
+                                       .UsingFactoryMethod(() => new 
AbstractCarProviderFactory().Create(new User { FiscalStability = 
FiscalStability.MrMoneyBags }))
+                                       .Named("ferrariProvider"),
+                               Component.For<ICarProvider>()
+                                       .UsingFactoryMethod(() => new 
AbstractCarProviderFactory().Create(new User { FiscalStability = 
FiscalStability.DirtFarmer }))
+                                       .Named("hondaProvider")
+                               );
 
-            Assert.IsInstanceOf(typeof(HondaProvider), 
kernel.Resolve<ICarProvider>("hondaProvider"));
-            Assert.IsInstanceOf(typeof(FerrariProvider), 
kernel.Resolve<ICarProvider>("ferrariProvider"));
-        }
+                       Assert.IsInstanceOf(typeof(HondaProvider), 
kernel.Resolve<ICarProvider>("hondaProvider"));
+                       Assert.IsInstanceOf(typeof(FerrariProvider), 
kernel.Resolve<ICarProvider>("ferrariProvider"));
+               }
 
-        [Test]
-        public void RegisterWithFactoryMethodAndKernelNamed()
-        {
-            kernel.Register(
-                Component.For<ICarProvider>()
-                    .UsingFactoryMethod(k => new 
AbstractCarProviderFactory().Create(new User { FiscalStability = 
FiscalStability.MrMoneyBags }))
-                    .Named("ferrariProvider"),
-                Component.For<ICarProvider>()
-                    .UsingFactoryMethod(k => new 
AbstractCarProviderFactory().Create(new User { FiscalStability = 
FiscalStability.DirtFarmer }))
-                    .Named("hondaProvider")
-                );
+               [Test]
+               public void RegisterWithFactoryMethodAndKernelNamed()
+               {
+                       kernel.Register(
+                               Component.For<ICarProvider>()
+                                       .UsingFactoryMethod(k => new 
AbstractCarProviderFactory().Create(new User { FiscalStability = 
FiscalStability.MrMoneyBags }))
+                                       .Named("ferrariProvider"),
+                               Component.For<ICarProvider>()
+                                       .UsingFactoryMethod(k => new 
AbstractCarProviderFactory().Create(new User { FiscalStability = 
FiscalStability.DirtFarmer }))
+                                       .Named("hondaProvider")
+                               );
 
-            Assert.IsInstanceOf(typeof(HondaProvider), 
kernel.Resolve<ICarProvider>("hondaProvider"));
-            Assert.IsInstanceOf(typeof(FerrariProvider), 
kernel.Resolve<ICarProvider>("ferrariProvider"));
-        }
+                       Assert.IsInstanceOf(typeof(HondaProvider), 
kernel.Resolve<ICarProvider>("hondaProvider"));
+                       Assert.IsInstanceOf(typeof(FerrariProvider), 
kernel.Resolve<ICarProvider>("ferrariProvider"));
+               }
 
                [Test]

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

File [modified]: FactorySupportFluentTestCase.cs
Delta lines: +3 -3
===================================================================

--- 
InversionOfControl/trunk/src/Castle.MicroKernel.Tests/Facilities/FactorySupport/FactorySupportProgrammaticTestCase.cs
       2010-01-07 21:36:56 UTC (rev 6594)
+++ 
InversionOfControl/trunk/src/Castle.MicroKernel.Tests/Facilities/FactorySupport/FactorySupportProgrammaticTestCase.cs
       2010-01-07 22:12:54 UTC (rev 6595)
@@ -15,10 +15,10 @@
 namespace Castle.Facilities.FactorySupport.Tests
 {
        using System;
-       using System.Collections.Generic;
+
        using Castle.MicroKernel;
-       using Core.Configuration;
-       using MicroKernel.Registration;
+       using Castle.MicroKernel.Registration;
+
        using NUnit.Framework;
 

File [modified]: FactorySupportProgrammaticTestCase.cs
Delta lines: +71 -4
===================================================================

--- 
InversionOfControl/trunk/src/Castle.MicroKernel.Tests/Facilities/FactorySupport/FactorySupportTestCase.cs
   2010-01-07 21:36:56 UTC (rev 6594)
+++ 
InversionOfControl/trunk/src/Castle.MicroKernel.Tests/Facilities/FactorySupport/FactorySupportTestCase.cs
   2010-01-07 22:12:54 UTC (rev 6595)
@@ -20,6 +20,8 @@
        using Castle.Core;
        using Castle.Core.Configuration;
        using Castle.Facilities.FactorySupport;
+       using Castle.MicroKernel.Facilities;
+       using Castle.MicroKernel.Registration;
        using Castle.MicroKernel.Tests.ClassComponents;
 
        using NUnit.Framework;
@@ -41,7 +43,7 @@
                        kernel.AddFacility("factories", new 
FactorySupportFacility());
                        kernel.AddComponentInstance("a", new CustomerImpl());
                }
-               
+
                [Test]
                public void DependancyIgnored()
                {
@@ -51,7 +53,7 @@
                        AddComponent("stringdictComponent", 
typeof(StringDictionaryDependentComponent), "CreateWithStringDictionary");
                        AddComponent("hashtableComponent", 
typeof(HashTableDependentComponent), "CreateWithHashtable");
                        AddComponent("serviceComponent", 
typeof(ServiceDependentComponent), "CreateWithService");
-                       
+
                        kernel.Resolve("hashtableComponent", 
typeof(HashTableDependentComponent));
                        kernel.Resolve("serviceComponent", 
typeof(ServiceDependentComponent));
                        kernel.Resolve("stringdictComponent", 
typeof(StringDictionaryDependentComponent));
@@ -67,12 +69,46 @@
 
                        model.Parameters.Add("someProperty", "Abc");
 
-                       MyCoolServiceWithProperties service = 
(MyCoolServiceWithProperties) kernel["cool.service"];
+                       var service = 
(MyCoolServiceWithProperties)kernel["cool.service"];
 
                        Assert.IsNotNull(service);
                        Assert.IsNull(service.SomeProperty);
                }
 
+               [Test]
+               public void CheckReturnValueFromTheFactory()
+               {
+                       kernel.AddFacility("factories", new 
FactorySupportFacility());
+                       kernel.Register(
+                               Component.For<PetFactory>().Parameters(
+                                       Parameter.ForKey("petType").Eq("dog"))
+                                       .Named("pet.factory"));
+                       kernel.Register(
+                               Component.For<Pet>().ImplementedBy<Cat>()
+                                       .Configuration(
+                                       
Attrib.ForName("factoryId").Eq("pet.factory"),
+                                       
Attrib.ForName("factoryCreate").Eq("Get"))
+                               );
+
+                       Assert.Throws(typeof(FacilityException), () => 
kernel.Resolve<Pet>());
+               }
+
+               [Test]
+               public void CheckReturnValueFromTheFactoryAccessor()
+               {
+                       kernel.AddFacility("factories", new 
FactorySupportFacility());
+                       kernel.Register(
+                               Component.For<PetFactory>()
+                                       .Named("pet.factory"));
+                       kernel.Register(
+                               Component.For<Pet>().ImplementedBy<Cat>()
+                                       .Configuration(
+                                       
Attrib.ForName("instance-accessor").Eq("Dog"))
+                               );
+                       Assert.Throws(typeof(FacilityException), () => 
kernel.Resolve<Pet>());
+               }
+
+
                private ComponentModel AddComponent(string key, Type type, 
string factoryMethod)
                {
                        MutableConfiguration config = new 
MutableConfiguration(key);
@@ -82,7 +118,7 @@
                        kernel.AddComponent(key, type);
                        return kernel.GetHandler(key).ComponentModel;
                }
-               
+
                public class Factory
                {
                        public static HashTableDependentComponent 
CreateWithHashtable()
@@ -137,5 +173,36 @@
                        {
                        }
                }
+
+               public class Cat : Pet
+               {
+                       public static Pet Dog
+                       {
+                               get { return new Dog(); }
+                       }
+               }
+               public class Dog : Pet
+               {
+               }
+               public class Pet
+               {
+               }
+               public class PetFactory
+               {
+                       private readonly string type;
+                       public PetFactory(string petType)
+                       {
+                               type = petType.ToLowerInvariant();
+                       }
+                       public Pet Get()
+                       {
+                               if (type == "cat")
+                                       return new Cat();
+                               else
+                                       return new Dog();
+                       }
+               }
+
+
        }

File [modified]: FactorySupportTestCase.cs
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