New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Lazy<T, TMetadata> incorrectly instantiates component when only querying for metadata #1

Open
tillig opened this Issue Jun 25, 2015 · 3 comments

Comments

Projects
None yet
1 participant
@tillig
Copy link
Contributor

tillig commented Jun 25, 2015

@tillig tillig changed the title Bug in MEF integration: Instantiates component when only querying for metadata Instantiates component when only querying for metadata Jun 25, 2015

@tillig

This comment has been minimized.

Copy link
Contributor

tillig commented Oct 27, 2016

Now that I've come out of the .NET Core haze, I'm getting a chance to look at this.

The bug appears to be due to the way we wire up Lazy<T, TMetadata> support not quite working with the way we tie MEF exports to each other.

Slight detour into the weeds:

In adapting MEF components to each other, we basically have to say "Export type Foo has ID 123 and importing type Bar takes a Foo, so tie that import to export ID 123." (Basically.) You can try following the code starting here. Every time you see a reference to a UniqueService object, that's mapping a type/export to a specific unique ID. Which is to say, it's not "typed" anymore. There are reasons for that which I won't get into here because it's not relevant.

Point being, this has the unfortunate side effect that, while it works for most things, it means when a property on an object that runs through Lazy<T, TMetadata> isn't going to make its way into the LazyWithMetadataRegistrationSource as a typed service, so the source is going to bypass it entirely It instead will fall back to some default behaviors and instantiate the object automatically, which is what this whole issue is about.

A workaround is to register the types consuming Lazy<T, TMetadata> with Autofac directly:

// After you register the part catalog, do this:
builder.RegisterType<ServiceConsumer>().PropertiesAutowired();

I'm not sure how to resolve this from a MEF integration standpoint at this time. I'll have to keep looking at it.

@tillig tillig added the bug label Oct 27, 2016

@tillig tillig changed the title Instantiates component when only querying for metadata Lazy<T, TMetadata> incorrectly instantiates component when only querying for metadata Oct 27, 2016

@tillig tillig added the help wanted label Oct 27, 2016

tillig pushed a commit that referenced this issue Oct 27, 2016

Travis Illig
@tillig

This comment has been minimized.

Copy link
Contributor

tillig commented Oct 27, 2016

Right now it looks like the best I can do is add a failing (skipped) unit test to try and verify the behavior when we get a chance to fix it. There are a couple of other issues here (like the one about allowing open generics) that makes me wonder if the MEF integration either needs some TLC and major overhaul or has potentially reached its limits given it's a convenience bridge rather than a 100% feature-for-feature mapping from MEF to Autofac.

If you have a PR for this, we'd be happy to take it.

@tillig

This comment has been minimized.

Copy link
Contributor

tillig commented Oct 27, 2016

I updated the Autofac + MEF docs to include this as a known issue.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment