Skip to content

IEnumerable<Scoped<T>> doesn't work as expected #230

Description

@jods4

Let's say your container contains many IFrob exports, let's call them Frob1 and Frob2.

If you want all of them you can Locate<IEnumerable<IFrob>>(), which will give you Frob1, Frob2.

Maybe you want to be able to spawn new frobs and locating IEnumerable<Func<IFrob>> does give you two factories. If you .Select(f => f()) then you end up with Frob1, Frob2, as expected.

Now let's say that in addition to that you want each factory to resolve in a new scope. You locate IEnumerable<Func<Scoped<IFrob>>> which returns 2 factories as expected. But (ignoring Dispose for now) if you look at .Select(f => f().Instance) then you'll notice every scoped instance resolves to the same IFrob: Frob2, Frob2 (based on priority, etc.)

It seems to me that Scoped "forgets" what specific IFrob it was supposed to be and just performs a plain Locate<IFrob> again, which is not what I want.
This makes Scoped<IFrob> useless/incompatible with IEnumerable. In fact, just locating IEnumerable<Scoped<IFrob>> returns Frob2, Frob2.

This is a simplified test case. My full code was:
IEnumerable<Meta<Func<string, Scoped<T>>>>
because on top of that I wanted per-IFrob meta information (before invoking the factory; meta infos seem to be right) and named scopes (seems to work ok as well).

Activity

  1. changed the title [-]IEnumerable<Func<Scoped<T>>> doesn't work as expected[/-] [+]IEnumerable<Scoped<T>> doesn't work as expected[/+] on Jul 25, 2019
  2. ipjohnson commented on Jul 25, 2019

    @ipjohnson
    Owner

    I see what you mean it's really not a robust implementation. I'll need to think about it a bit to see what's the best solution for this.

  3. jods4 commented on Jul 25, 2019

    @jods4
    CollaboratorAuthor

    Can you advise a workaround in the meantime? I'm having a hard time figuring out how to do this any other way.

    I want to be able:

    • know about every IFrob, especially their metadata.
    • instantiate specific IFrob on demand, in their own scope.
  4. ipjohnson commented on Jul 31, 2019

    @ipjohnson
    Owner

    Sorry meant to reply this weekend. There isn't a good work around for the moment but I do think I should be able to find some time this weekend to fix it properly and do a beta release.

  5. jods4 commented on Jul 31, 2019

    @jods4
    CollaboratorAuthor

    Thanks.

    FWIW I managed to workaround the problem but it's very convoluted.
    I used named exports instead metadata; then i'm casting the IExportLocatorScope to DependencyInjectionContainer so that I can use StrategyCollectionContainer.GetActivationStrategyCollection to enumerate all keys and metadata related to an interface; finally I can create a lifetime scope and Locate the interface and key previously gathered to find the instance that I want.

    It's ugly :(
    but it works for now.

  6. ipjohnson commented on Aug 5, 2019

    @ipjohnson
    Owner

    I have one more issue I need to address before I can do a beta release but you can test the fix in the nightly nuget feed

    https://ci.appveyor.com/nuget/grace-master

  7. jods4 commented on Aug 5, 2019

    @jods4
    CollaboratorAuthor

    Thanks!
    Switching feeds is a bit complicated (don't ask) but if you do a prerelease on Nuget I can test.
    Otherwise I can wait a little bit more.

  8. ipjohnson commented on Aug 11, 2019

    @ipjohnson
    Owner

    I've released a new version 7.1.0-beta

  9. jods4 commented on Aug 12, 2019

    @jods4
    CollaboratorAuthor

    Thanks, I referenced the 7.1 beta and it works now! ❤️

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions