LifestyleBoundTo - can't resolve whole collection where one of items is scoped.

124 views
Skip to first unread message

Sławomir Siudek

unread,
Jan 22, 2015, 4:04:27 PM1/22/15
to castle-pro...@googlegroups.com
Hi

Firstly I wanted to report my thoughts in http://issues.castleproject.org/ as a bug description, but the page doesn't work - it only redirects to github 'castle-youtrack-export' page, so need to discuss the issue here.

Scenario:
I use some different types of, let say, 'ViewModels', where all of ViewModel-types use some services but with different implementations. The natural way of implement this is register all available services implementations and resolve them per ViewModel instance

I believe that the unit test below describes my idea and expectation. Please run the test - it fails.

    [TestFixture]
    public sealed class BoundedLifestyleTests
    {
        class ViewModel
        {
            public IService[] Services { get; set; }
        }

        public interface IService { }
        class NeutralStrategy : IService { }
        class SpecializedStrategy : IService { }

        /// <summary>
        /// I have some IService implementations, where the are either are neutral (could be used in any context)
        /// or are specialized (should be resolved only in ViewModel).
        /// I would like to implement that requirement with LifestyleBoundTo which looks promising.
        /// </summary>
        [Test]
        public void Test()
        {
            var container = new WindsorContainer();
            container.Kernel.Resolver.AddSubResolver(new CollectionResolver(container.Kernel, true));

            container.Register(
                Component.For<IService>().ImplementedBy<NeutralStrategy>(),
                Component.For<ViewModel>(),
                Component.For<IService>().ImplementedBy<SpecializedStrategy>().LifestyleBoundTo<ViewModel>());

            // ViewModel has neutral and specialized strategies resolved.
            var viewModel = container.Resolve<ViewModel>();
            Assert.That(viewModel.Services.Select(o => o.GetType()), Is.EquivalentTo(new[] { typeof(NeutralStrategy), typeof(SpecializedStrategy) }));

            // Outside of a graph bound to ViewModel, we still should be able to resolve neutral strategy.
            var neutralStrategies = container.ResolveAll<IService>();
            Assert.That(neutralStrategies.Select(o => o.GetType()), Is.EquivalentTo(new[] { typeof(NeutralStrategy) }));
        }
    }

Regards

Slawek

Carlos Cocom

unread,
Jan 22, 2015, 6:58:15 PM1/22/15
to castle-pro...@googlegroups.com
well maybe its not qualify how beautiful code but work

Named each implementation and using "DependsOn" register it

a better approach be register all implementation

            container.Register(Classes.FromThisAssembly()
               .BasedOn<IService>()
               .LifestyleTransient()
             );

and on depends set it, but i dont know

container.Register(
                Component.For<ViewModel>()
                    .DependsOn(Dependency.OnComponentCollection("Services", new []{ typeof(IService) }))
                );


Here the working example


[TestFixture]
    public sealed class BoundedLifestyleTests
    {
        class ViewModel
        {
            public IService[] Services { get; set; }
        }

        public interface IService { }
        class NeutralStrategy : IService { }
        class SpecializedStrategy : IService { }

        /// <summary>
        /// I have some IService implementations, where the are either are neutral (could be used in any context)
        /// or are specialized (should be resolved only in ViewModel).
        /// I would like to implement that requirement with LifestyleBoundTo which looks promising.
        /// </summary>
        [Test]
        public void Test()
        {
            var container = new WindsorContainer();
            container.Kernel.Resolver.AddSubResolver(new CollectionResolver(container.Kernel, true));

            //container.Register(Classes.FromThisAssembly()
            //   .BasedOn<IService>()
            //   .LifestyleTransient()
            //   );

            container.Register(
               Component.For<IService>()
               .ImplementedBy<NeutralStrategy>()
               .Named("se1")
               .LifeStyle.Transient
               );

            container.Register(
                Component.For<IService>()
                .ImplementedBy<SpecializedStrategy>()
                .Named("se2")
                .LifeStyle.Transient
                );

            container.Register(
                Component.For<ViewModel>()
                    .DependsOn(Dependency.OnComponentCollection("Services", new string[]{"se1","se2"}))
                    //.DependsOn(Dependency.OnComponentCollection("Services", new []{ typeof(IService) }))
                );

            // ViewModel has neutral and specialized strategies resolved.
            var viewModel = container.Resolve<ViewModel>();
            //Console.WriteLine("viewmodel can " + viewModel.Services.Count);
            Assert.That(viewModel.Services.Select(o => o.GetType()), Is.EquivalentTo(new[] { typeof(NeutralStrategy), typeof(SpecializedStrategy) }));

            // Outside of a graph bound to ViewModel, we still should be able to resolve neutral strategy.
            var neutralStrategies = container.ResolveAll<IService>();
            Assert.That(neutralStrategies.Select(o => o.GetType()), Is.EquivalentTo(new[] { typeof(NeutralStrategy), typeof(SpecializedStrategy) } ));
        }
    }


regards

--
You received this message because you are subscribed to the Google Groups "Castle Project Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to castle-project-u...@googlegroups.com.
To post to this group, send email to castle-pro...@googlegroups.com.
Visit this group at http://groups.google.com/group/castle-project-users.
For more options, visit https://groups.google.com/d/optout.

hammett

unread,
Jan 22, 2015, 8:12:40 PM1/22/15
to castle-pro...@googlegroups.com
neutralStrategies? seems like you're doing some interesting stuff there!
--
Cheers,
hammett
http://www.d-collab.com/
http://www.hammettblog.com/

veihan

unread,
Jan 23, 2015, 2:24:43 AM1/23/15
to castle-pro...@googlegroups.com
Hi, 

I run your code with multiple combination and all fails at resolving all IService.
I saw on few posts on QA forums that programmers mostly resolve bounded to 
objects only (ex. ViewModels). 

Always better inject than service locate.


Try some other life style maybe it will fix your problem.


regards

To unsubscribe from this group and stop receiving emails from it, send an email to castle-project-users+unsub...@googlegroups.com.
Reply all
Reply to author
Forward
0 new messages