That's a known issue/feature, and the reason for that was to handle scenarios where with default selector you had factory method named like GetFoo. In that case factory would first try to get component named "Foo" and then fallback to getting it by type if not found. The problem is no distinction was being made between this implicit lookup by name and implicit one, when you specify the name yourself in a custom selector.

This is handled a bit better in v3 which makes the distinction and if you request lookup by name explicitly the lookup will fail if component with that name is not present. If you don't want to upgrade to v3 just yet, I think your option is to use custom selector that returns custom TypedFactoryComponent and override Resolve method of the component to provide your desired behaviour.

HTH,
Krzysztof

On 17/08/2011 9:43 AM, Scott_M wrote:
I have a typed factory with a custom selector. I basically need to be able to have a typed factory that selects the component via componentName passed in as a method argument to the factory method. It all seems to work when I pass a valid componentName in. However, when I pass an invalid componentName in things go afoul. Specifically, castle somehow manages to match another component that has the correct type but wrong name. How do you force castle to return null or throw an error in this situation? Here is my code:


IWindsorContainer container = new WindsorContainer();

            //must register typed factory facility otherwise we get errors
            container.AddFacility<TypedFactoryFacility>();

            container.Register(
Component.For<IFoo>().ImplementedBy<Foo1>().Named("Foo1").LifeStyle.Transient, Component.For<IFoo>().ImplementedBy<Foo2>().Named("Foo2").LifeStyle.Transient, Component.For<IFooFactoryWithArgs>().AsFactory(c => c.SelectedWith("MySelector")), Component.For<ITypedFactoryComponentSelector>().ImplementedBy<SelectorByComponentName>().Named("MySelector")
                );

IFooFactoryWithArgs factory = container.Resolve<IFooFactoryWithArgs>();

IFoo foo = factory.GetFoo("Foo3"); //Note, there is no component registered with Foo3 so I would expect NULL to be returned or an error thrown at this point. Unfortunately, Foo1 is returned.

            Assert.IsNotNull(foo);

            Assert.IsTrue(foo.GetType() == typeof(Foo2));

public class SelectorByComponentName : DefaultTypedFactoryComponentSelector
    {
protected override string GetComponentName(MethodInfo method, object[] arguments)
        {
            bool found = false;
            int position = -1;
            object componentArgument = null;
            string componentName = null;

            ParameterInfo[] pInfos = method.GetParameters();
            if (pInfos != null)
            {
                foreach (ParameterInfo pInfo in pInfos)
                {
                    if (pInfo.Name.ToLower() == "componentname")
                    {
                        found = true;
                        position = pInfo.Position;
                        break;
                    }
                }
            }

            if (!found)
            {
throw new ApplicationException("The current component selctor did not find a 'componentname' argument for the current factory method.");
            }

            componentArgument = arguments[position];
            if (componentArgument == null)
            {
throw new ApplicationException("The current component selctor found a null 'componentname' argument for the current factory method.");
            }

componentName = componentArgument.ToString(); //no way to validate that we have a valid / registered component name
            if (String.IsNullOrEmpty(componentName))
            {
throw new ApplicationException("The current component selctor found a null or empty 'componentname' argument for the current factory method.");
            }

            return componentName;
        }

protected override IDictionary GetArguments(MethodInfo method, object[] arguments)
        {
            var argumentMap = new Arguments();

            return argumentMap;  //No additional arguments
        }
    }

--
You received this message because you are subscribed to the Google Groups "Castle Project Users" group. To view this discussion on the web visit https://groups.google.com/d/msg/castle-project-users/-/VW5vNsD15UIJ. 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-users?hl=en.

--
You received this message because you are subscribed to the Google Groups "Castle 
Project Users" 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-users?hl=en.

Reply via email to