ipjohnson / Grace

Grace is a feature rich dependency injection container library
MIT License
336 stars 33 forks source link

Creating dynamic instances by key #247

Open silkfire opened 4 years ago

silkfire commented 4 years ago

I have the following scenario but am not sure how to solve it in Grace:

A service requires a dependency that is resolved with a string parameter sent to its constructor.

  1. If the dependency has been resolved with this argument before, let Grace serve it (singleton),
  2. If not, then create the dependency with the provided parameter and register is as singleton.

The argument is resolved dynamically from another dependency.

So is there a way in ExportFactory<DependencyProvidingDynamicArgument, IDependency> to cache instances by a dynamic key?

ipjohnson commented 4 years ago

There isn't something out of the box like that but I think it could be do able with a custom lifestyle. I'm assuming somewhere you would be doing

container.Locate<SomeType>(extraData: new { key = "SomeString"});

ipjohnson commented 4 years ago

Actually I forgot I do have something like this out of the box SingletonPerKey.

silkfire commented 4 years ago

@ipjohnson That's brilliant, huge thanks. Is the SingletonPerKey smart enough to not re-register the service if I provide it an already registered key?

If I run this:

container.Configure(c => c.Export<BasicService>().Lifestyle.SingletonPerKey((scope,context) => "A"));
container.Configure(c => c.Export<BasicService>().Lifestyle.SingletonPerKey((scope,context) => "A"));

Will it just silently ignore the second line?

ipjohnson commented 4 years ago

Sorry meant to reply to this yesterday and got side tracked. I think I might have misunderstood yesterday what you are looking for. Are you looking to do

The code you have there essentially will only return one instance because the function always returns "A".

silkfire commented 4 years ago

I was thinking a combination of both. Cache an instance based on a key (which is also a constructor argument to the type being resolved) that is different depending on what the func returns during runtime. Unless I'm getting confused here :)

ipjohnson commented 4 years ago

Hmmm ok well that could work, to answer your previous question the registration will just replace when you get one instance. If you get an enumeration of them you will get two.