Jose, Pat

I ran your test and I did reproduce your issue. This is a known limitation in Windsor right now that goes back to the early days.
http://castle.uservoice.com/forums/38955-windsor-v3/suggestions/455402-get-rid-of-the-arbitrary-division-for-service-para?ref=title

In short, Windsor has three "kinds" of dependencies:
services (the most common one: from the container give me any component's instance that support this service)
service overrides (from the container give me specific component's instance)
parameters (which is used for things like strings, ints etc: from the component's configuration/local context give me the value)

Notice that for parameters it does not look in the container. The problem is - for this dependency Windsor treats it as parameter (like I said - the division is very arbitrary and sometimes gets it wrong).

For current version probably the best workaround is to use DynamicParameters to provide the value...


for the next version (codenamed Wawel) we accept patches :)

On 08/01/2011 11:21 PM, José F. Romaniello wrote:
sorry the exception that i got is

Can't create component 'X.Tests.SomeService' as it has dependencies to be satisfied.
X.Tests.SomeService is waiting for the following dependencies:

Keys (components with specific keys)
- samples which was not registered.



2011/1/8 José F. Romaniello <[email protected] <mailto:[email protected]>>

    Yes, Ive tested and i've same problem here:

    [TestFixture]

    public class CastleTest

    {

    [Test]

    public void Test()

    {

    var container = new WindsorContainer();

    container.AddFacility<FactorySupportFacility>();

    container.Register(Component.For<IEnumerable<ISample>>()

    .UsingFactoryMethod(k => Mocks.Of<ISample>().Where(s => s.Name ==
    "Test").Take(10).ToArray()),

    Component.For<SomeService>());

    container.Resolve<IEnumerable<ISample>>().Count().Should().Be.EqualTo(10);

    var service = container.Resolve<SomeService>();

    service.CountSamples().Should().Be.EqualTo(10);

    }

    }

    public class SomeService

    {

    private readonly IEnumerable<ISample> samples;

    public SomeService(IEnumerable<ISample> samples)

    {

    this.samples = samples;

    }

    public int CountSamples()

    {

    return samples.Count();

    }

    }

    public interface ISample

    {

    string Name { get; set; }

    }


    I've never done this before, so i am confused too. and this
    confused me:

    Why is Windsor not able to inject array or list of components?
    
http://stw.castleproject.org/Windsor.FAQ.ashx#Why_is_Windsor_not_able_to_inject_array_or_list_of_components_8

    Windsor, *by default when you have dependency on IFoo[],
    IEnumerable<IFoo> or IList<IFoo> will check if you have a
    component registered for that exact type (array or list of IFoo),*
    not if you have any components registered for IFoo (array of
    components, is not the same as a component which is an array). You
    can change the behavior to say "When you see array or list of IFoo
    just give me all IFoos you can get" you use CollectionResolver.



    2011/1/8 pmcg <[email protected] <mailto:[email protected]>>

        José

        I did look at CollectionResolver, but that solves a different
        problem
        than what I am trying to achieve. I will not have registered
        all the
        apples in the container, I want to get the apples from the apple
        factory and hence i have configured the apples component as
        transient
        which allows me to use the factory method every time i need to
        satisfy
        an apples dependency. This means the dependency collection is
        dynamic
        and can change over time etc.
        I have used a pretty simple example to illustrate, but i would
        expect
        the problem is not uncommon i.e. a repository backed
        collection which
        is a dependancy for another component ?


        Thanks
        Pat



        On Jan 8, 12:09 pm, José F. Romaniello <[email protected]
        <mailto:[email protected]>> wrote:
        > There is a resolver for that, you can use:
        > container.Kernel.Resolver.AddSubResolver(new
        > CollectionResolver(container.Kernel, true));
        >
        > then you can register all your Apples as such, and inject
        > IEnumerable<Apple>, Apple[], IList<Apple> or ICollection<Apple>
        >
        > (More info
        here:http://stw.castleproject.org/Windsor.Resolvers.ashx)
        >
        > So, you wouldn't need a factory or anything else.
        >
        > Maybe IEnumerable<T> are handled differently, not sure about
        this.
        >
        > 2011/1/8 pmcg <[email protected] <mailto:[email protected]>>
        >
        > > Hi,
        > > I'm trying to understand why when I have a registered an
        IEnumerable
        > > component, which I can resolve using a normal resolve
        method call, the
        > > container will not satisfy another component's resolution
        call where
        > > this second component has the same IEnumerable type
        dependency. I have
        > > managed to get it to work using the DynamicParameters
        registration
        > > helper method. I guess I could also get it to work using
        service
        > > overrides.
        > > Note I am using a factory method to create the IEnumerable
        component.
        >
        > > This simple example illustrates what I’m trying to
        understand, if you
        > > remove the DynamicParameters usage in the Worker component
        > > registration, its apples dependency will not be satisfied,
        even though
        > > we could resolve the apples collection when doing so
        directly against
        > > the container
        >
        > > Should the container not be able to satisfy the Worker apples
        > > dependency without the help of DynamicParameters ?
        >
        > > Thanks in advance
        > > Pat
        >
        > > var _container = new WindsorContainer();
        > > _container.AddFacility("factorySupport", new
        > > FactorySupportFacility());
        >
        > > _container.Register(
        > > Component.For<AppleFactory>()
        > >  .Named("appleFactory"));
        >
        > > _container.Register(
        > > Component.For<IEnumerable<Apple>>()
        > >  .Named("apples")
        > >  .LifeStyle.Transient
        > >  .UsingFactoryMethod(kernel =>
        > > kernel.Resolve<AppleFactory>().GetAll()));
        >
        > > // If i don't include the DynamicParameters statement -
        Could not
        > > resolve non-optional dependency for 'worker' (Worker).
        Parameter
        > > 'apples' type
        'System.Collections.Generic.IEnumerable`1[[Apple,
        > > ConsoleApplication1, Version=1.0.0.0, Culture=neutral,
        > > PublicKeyToken=null]]'
        > > _container.Register(
        > > Component.For<Worker>()
        > >  .Named("worker")
        > >  .LifeStyle.Transient
        > >  .DynamicParameters((kernel, parameters) => {
        parameters["apples"] =
        > > (kernel.Resolve<AppleFactory>()).GetAll(); }));  // Could
        have just
        > > used the apple factory directly here but i may want
        caching\logging
        > > etc logic
        >
        > > var _apples = _container.Resolve<IEnumerable<Apple>>();
        > > Console.WriteLine("Managed to resolve apples component,
        count = {0}",
        > > _apples.Count());
        >
        > > Console.WriteLine("Now trying to resolve a worker which
        has an apples
        > > dependancy which fails ");
        > > var _worker = _container.Resolve<Worker>();
        > > _worker.DoIt();
        >
        > > --
        > > 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]
        <mailto:[email protected]>
        > > .
        > > To unsubscribe from this group, send email to
        > > [email protected]
        
<mailto:castle-project-users%[email protected]><castle-project-users%[email protected]
        <mailto:castle-project-users%[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]
        <mailto:[email protected]>.
        To unsubscribe from this group, send email to
        [email protected]
        <mailto:castle-project-users%[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.

--
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