Closed GoogleCodeExporter closed 8 years ago
I discovered this issue while using the
Autofac.Integration.Web.Forms.InjectProperties attribute, but it seems to
affect only the Core library.
Original comment by biscuita...@gmail.com
on 22 May 2012 at 9:41
After searching through the source code, and wiki, I discovered this is correct
behavior based on this page:
http://code.google.com/p/autofac/wiki/RelationshipTypes
I disabled the default behaviors (using a flag that doesn't seem to be
documented anywhere):
var builder = new ContainerBuilder();
var container = builder.Build(ContainerBuildOptions.ExcludeDefaultModules);
But this caused MVC integration to fail because it relies heavily on
IEnumerable/Meta/Lazy behavior in the default modules.
It seems the creation of the IEnumerable<TypeName> happens on
context.IsRegistered(IEnumerable<TypeName>). Is it possible for this to return
false instead of creating an empty TypeName[] if there are no TypeName objects
in the container?
With the current behaviour, my public IEnumerable<TypeName> {get;set;} that I
have defined lots of places in my ASP.NET pages and also MVC Controllers are
getting set with empty arrays and then overwritten. It seems like they should
not be set in the first place if there are no TypeName objects in the container.
Original comment by biscuita...@gmail.com
on 23 May 2012 at 6:56
Hi there - glad you were able to get to the bottom of this. If you use
ExcludeDefaultModules, you can re-add the ones you need using code like:
builder.RegisterSource(new LazyRegistrationSource())
etc... You could then register a modified version of the default
CollectionRegistrationSource (responsible for IEnumerable etc) that does not
return results when the element type is not registered.
Not a lot of other simple options that I can think of, hope you have some
success working through this.
Regarding MVC controllers, you may be able to turn off (not turn on) property
injection, and instead use an OnActivated() handler to perform property
injection selectively (e.g. ignoring properties on base types).
Nick
Original comment by nicholas...@gmail.com
on 24 May 2012 at 5:00
Thanks for the response. LazyRegsitrationSource is not a public class (nor are
any of the IRegistrationSource implementations). I tried to use
ExcludeDefaultModules and re-register everything but
CollectionRegistrationSource, and it didn't work.
It seems to me that the container should return something when you call
c.Resolve<IEnumerable<TypeName>> *only* if there has been one or more TypeName
objects registered in the container. Otherwise Resolve should throw and
IsRegistered should return false. I don't see the usefulness of returning an
empty array.
It only affected one control in my code: IEnumerable<string> PropertyName had a
set method that was accessing an injected property that had not yet been
injected. I was able to work around it in this case.
Original comment by biscuita...@gmail.com
on 24 May 2012 at 3:28
Thanks for following up. There are pros and cons to each approach, we don't
plan to change this but want to make sure that the right workarounds are in
place in situations like the one you've identified. Thanks again for the report!
Original comment by nicholas...@gmail.com
on 16 Jun 2012 at 3:13
I just added Autofac to a webforms project ran into this trap. I am wondering
if you could describe what the pros of the current implementation are. Seems
like a pretty nasty surprise.
Original comment by mte...@gmail.com
on 15 Apr 2013 at 7:03
The issue is no longer about which approach is better, it is the fact that
there is now a great deal of code that will be relying on this behaviour, and
changing it will break that code.
Original comment by alex.meyergleaves
on 16 Apr 2013 at 1:39
Original issue reported on code.google.com by
biscuita...@gmail.com
on 22 May 2012 at 9:36Attachments: