InjectProperties and arrays

101 views
Skip to first unread message

Bogdan Cucosel (James)

unread,
Mar 4, 2010, 3:32:46 PM3/4/10
to Autofac
Hello,

I am using the InjectProperties method of the IComponentContext
implementation to inject properties into a component.

The component has a settable property of an array type.

Althoug the type of item of the array is not registered in the
container

this.container.IsRegistered(typeof(Teamnet.Core.Interfaces.FilterItem))
returns false

the array is set to an empty array and

this.container.IsRegistered(typeof(Teamnet.Core.Interfaces.FilterItem[]))
returns true.


Can you please tell me , is this a bug or is it something i am
missing ?

Thank you

Carl Hörberg

unread,
Mar 5, 2010, 2:20:22 AM3/5/10
to autofac
doesn't the array property on your component gets populated or whats the problem? 


--
You received this message because you are subscribed to the Google Groups "Autofac" group.
To post to this group, send email to aut...@googlegroups.com.
To unsubscribe from this group, send email to autofac+u...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/autofac?hl=en.


Carl Hörberg

unread,
Mar 5, 2010, 2:25:30 AM3/5/10
to autofac
because i just wrote this test case, and it passes:

        class HasCollectionProperty
        {
            public string[] Val { get; set; }
        }

        [Test]
        public void PropertyCollectionInjection()
        {
            var s1 = "foo";
            var s2 = "bar";

            var builder = new ContainerBuilder();
            builder.RegisterInstance(s1);
            builder.RegisterInstance(s2);
            builder.RegisterType<HasCollectionProperty>().PropertiesAutowired();

            var container = builder.Build();

            var instance = container.Resolve<HasCollectionProperty>();

            Assert.IsNotNull(instance);
            Assert.Contains(s1, instance.Val);
            Assert.Contains(s2, instance.Val);

Bogdan Cucosel (James)

unread,
Mar 5, 2010, 7:08:10 AM3/5/10
to Autofac
Hello,

The array gets populated , that is the problem.

I do not have the strings s1 and s2 registered in the container, but
the HasCollectionProperty.Val property gets populated with an empty
string array.

I worked around this by setting ExcludeDefaultModules to false on the
container; this makes the container not load
CollectionRegistrationSource.

On Mar 5, 9:25 am, Carl Hörberg <carl.hoerb...@gmail.com> wrote:
> because i just wrote this test case, and it passes:
>
>         class HasCollectionProperty
>         {
>             public string[] Val { get; set; }
>         }
>
>         [Test]
>         public void PropertyCollectionInjection()
>         {
>             var s1 = "foo";
>             var s2 = "bar";
>
>             var builder = new ContainerBuilder();
>             builder.RegisterInstance(s1);
>             builder.RegisterInstance(s2);
>
>  builder.RegisterType<HasCollectionProperty>().PropertiesAutowired();
>
>             var container = builder.Build();
>
>             var instance = container.Resolve<HasCollectionProperty>();
>
>             Assert.IsNotNull(instance);
>             Assert.Contains(s1, instance.Val);
>             Assert.Contains(s2, instance.Val);
>         }
>
>
>
> On Fri, Mar 5, 2010 at 08:20, Carl Hörberg <carl.hoerb...@gmail.com> wrote:
> > doesn't the array property on your component gets populated or whats the
> > problem?
>

> > On Thu, Mar 4, 2010 at 21:32, Bogdan Cucosel (James) <bogdan...@gmail.com>wrote:
>
> >> Hello,
>
> >> I am using the InjectProperties method of the IComponentContext
> >> implementation to inject properties into a component.
>
> >> The component has a settable property of an array type.
>
> >> Althoug the type of item of the array is not registered in the
> >> container
>
> >> this.container.IsRegistered(typeof(Teamnet.Core.Interfaces.FilterItem))
> >> returns false
>
> >> the array is set to an empty array  and
>
> >> this.container.IsRegistered(typeof(Teamnet.Core.Interfaces.FilterItem[]))
> >> returns true.
>
> >> Can you please tell me , is this a bug or is it something i am
> >> missing ?
>
> >> Thank you
>
> >> --
> >> You received this message because you are subscribed to the Google Groups
> >> "Autofac" group.
> >> To post to this group, send email to aut...@googlegroups.com.
> >> To unsubscribe from this group, send email to

> >> autofac+u...@googlegroups.com<autofac%2Bunsu...@googlegroups.com­>


> >> .
> >> For more options, visit this group at

> >>http://groups.google.com/group/autofac?hl=en.- Hide quoted text -
>
> - Show quoted text -

Bogdan Cucosel (James)

unread,
Mar 5, 2010, 3:46:35 AM3/5/10
to Autofac
Hello,

Yes, the array gets populated an that is the problem.
I do not register strings s1 and s2, hence the array should not be
populated.

A temporary fix for me is to build the container without the the
default modules (ExcludeDefaultModules) wich does not register the
CollectionRegistrationSource, but I suspect I will be sorry for this
later.

So the problem is that, even if I do not register the 2 strings like
you do, the array will be assigned to a empty string array.


On Mar 5, 9:25 am, Carl Hörberg <carl.hoerb...@gmail.com> wrote:

> because i just wrote this test case, and it passes:
>
>         class HasCollectionProperty
>         {
>             public string[] Val { get; set; }
>         }
>
>         [Test]
>         public void PropertyCollectionInjection()
>         {
>             var s1 = "foo";
>             var s2 = "bar";
>
>             var builder = new ContainerBuilder();
>             builder.RegisterInstance(s1);
>             builder.RegisterInstance(s2);
>
>  builder.RegisterType<HasCollectionProperty>().PropertiesAutowired();
>
>             var container = builder.Build();
>
>             var instance = container.Resolve<HasCollectionProperty>();
>
>             Assert.IsNotNull(instance);
>             Assert.Contains(s1, instance.Val);
>             Assert.Contains(s2, instance.Val);
>         }
>
>
>
> On Fri, Mar 5, 2010 at 08:20, Carl Hörberg <carl.hoerb...@gmail.com> wrote:
> > doesn't the array property on your component gets populated or whats the
> > problem?
>

> > On Thu, Mar 4, 2010 at 21:32, Bogdan Cucosel (James) <bogdan...@gmail.com>wrote:
>
> >> Hello,
>
> >> I am using the InjectProperties method of the IComponentContext
> >> implementation to inject properties into a component.
>
> >> The component has a settable property of an array type.
>
> >> Althoug the type of item of the array is not registered in the
> >> container
>
> >> this.container.IsRegistered(typeof(Teamnet.Core.Interfaces.FilterItem))
> >> returns false
>
> >> the array is set to an empty array  and
>
> >> this.container.IsRegistered(typeof(Teamnet.Core.Interfaces.FilterItem[]))
> >> returns true.
>
> >> Can you please tell me , is this a bug or is it something i am
> >> missing ?
>
> >> Thank you
>
> >> --
> >> You received this message because you are subscribed to the Google Groups
> >> "Autofac" group.
> >> To post to this group, send email to aut...@googlegroups.com.
> >> To unsubscribe from this group, send email to

> >> autofac+u...@googlegroups.com<autofac%2Bunsu...@googlegroups.com­>


> >> .
> >> For more options, visit this group at

Carl Hörberg

unread,
Mar 6, 2010, 10:21:16 AM3/6/10
to autofac
indeed, that sounds like a bug, doesn't it Nicholas Blumhardt or Rinat Abdullin? should i fix it? 

To unsubscribe from this group, send email to autofac+u...@googlegroups.com.

Nicholas Blumhardt

unread,
Mar 8, 2010, 1:51:27 AM3/8/10
to aut...@googlegroups.com
No, this one is by design. Autofac assumes that what you're injecting properties into is a component - if you want to use autowired property injection, expect that anything settable will be set.

One alternative is to be explicit:

class HasCollectionProperty
{
    public IFoo Foo { get; set; }

    public string[] Val { get; set; }
}


builder.RegisterType<HasCollectionProperty>()
    .OnActivating(e => e.Instance.Foo = e.Context.Resolve<IFoo>());

The catch-22 of automatically resolving all instances of a service via IEnumerable is that empty collections are still valid (something that accepts zero-or-more should always accept zero.)

As with almost all wiring problems, constructor injection is the best solution.

Constructors play a special role on components in expressing dependencies - that is their only purpose and they can be very clearly interpreted by tooling. Methods and properties play (many) different roles, so tooling has to guess much more about their semantics.

Carl Hörberg

unread,
Mar 8, 2010, 2:49:52 AM3/8/10
to autofac
aha :) 

Bogdan Cucosel (James)

unread,
Mar 9, 2010, 1:06:10 PM3/9/10
to Autofac
Hello,

I do not entirely agree with the statment "anything settable should be
set".
I think that "anything settable and available should be set".
For me it seems a bit pointless to inject an empty array. This is not
helpfull in any way.
Why not leave it the way it is if the array type is not registered
with the container ?


I will be using ctor injection , but actually that is the way I
originally used it, and then I needed to set the properties, that's
why i made the properties settable.
Thank you very much


On Mar 8, 8:51 am, Nicholas Blumhardt <nicholas.blumha...@gmail.com>
wrote:


> No, this one is by design. Autofac assumes that what you're injecting
> properties into is a component - if you want to use autowired property
> injection, expect that anything settable will be set.
>
> One alternative is to be explicit:
>
> class HasCollectionProperty
> {
>     public IFoo Foo { get; set; }
>     public string[] Val { get; set; }
>
> }
>
> builder.RegisterType<HasCollectionProperty>()
>     .OnActivating(e => e.Instance.Foo = e.Context.Resolve<IFoo>());
>
> The catch-22 of automatically resolving all instances of a service via
> IEnumerable is that empty collections are still valid (something that
> accepts zero-or-more should always accept zero.)
>
> As with almost all wiring problems, constructor injection is the best
> solution.
>
> Constructors play a special role on components in expressing dependencies -
> that is their only purpose and they can be very clearly interpreted by
> tooling. Methods and properties play (many) different roles, so tooling has
> to guess much more about their semantics.
>

> On 7 March 2010 01:21, Carl Hörberg <carl.hoerb...@gmail.com> wrote:
>
>
>
> > indeed, that sounds like a bug, doesn't it Nicholas Blumhardt or Rinat
> > Abdullin? should i fix it?
>

> >> <autofac%2Bunsu...@googlegroups.com<autofac%252Bunsubscribe@googlegroup­s.com>


> >> ­>
> >> > >> .
> >> > >> For more options, visit this group at

> >> > >>http://groups.google.com/group/autofac?hl=en.-Hide quoted text -


>
> >> > - Show quoted text -
>
> >> --
> >> You received this message because you are subscribed to the Google Groups
> >> "Autofac" group.
> >> To post to this group, send email to aut...@googlegroups.com.
> >> To unsubscribe from this group, send email to

> >> autofac+u...@googlegroups.com<autofac%2Bunsu...@googlegroups.com­>
> >> .
> >> For more options, visit this group at

> >>http://groups.google.com/group/autofac?hl=en.
>
> >  --
> > You received this message because you are subscribed to the Google Groups
> > "Autofac" group.
> > To post to this group, send email to aut...@googlegroups.com.
> > To unsubscribe from this group, send email to

Reply all
Reply to author
Forward
0 new messages