0

I'm trying to determine how I could inject a specific instance of a service when resolving a type.

For example with Unity I might do something like:

IFoo fooService = Container.Resolve<IFoo>();
fooSerivce.DoBar( "someParameter" );
ParameterOverrides overrides = new ParameterOverrides()
{
    { "fooService", fooService }
};
return Container.Resolve( type, overrides );

How would I accomplish this with Simple Injector?

Steven
  • 166,672
  • 24
  • 332
  • 435
Dan Siegel
  • 5,724
  • 2
  • 14
  • 28
  • Can you show a concrete example of when you need this? – Steven Jan 23 '17 at 23:57
  • An example of this would be with the [Prism Library](https://github.com/PrismLibrary/Prism/blob/master/Source/Xamarin/Prism.Unity.Forms/PrismApplication.cs#L25) – Dan Siegel Jan 24 '17 at 00:20

1 Answers1

1

Simple Injector has no built-in support for supplying the container's 'resolve' method, because this a bad idea in general since its main use case is to supply injection constructors with runtime data. Having the construction of your application components depend on runtime data is an anti-pattern, as expressed in detail here.

There are some rare cases though where you can't work around this, which mainly happens when integrating with 3rd party linraries or frameworks that are out of your control to change. You might be hitting such case with Prism, which seems to be designed around having a cyclic dependency between the page and the navigation service, which is the main reason why prism is doing this.

You should take a look at this particular Q&A. It talks about WebFromsMvp which has the same design quirk as Prism does. The question and answer describe a way to work around this quite effectively with Simple Injector.

UPDATE

From the example you show in your question, there doesn't seem a need to use overrides at all, since you inject a service that has been resolved from the container. Instead you can do the following:

IFoo fooService = Container.GetInstance<IFoo>();
fooSerivce.DoBar("someParameter");
return Container.GetInstance(type);

As long as IFoo is registered with a Scoped or Singleton lifestyle, and type accepts an IFoo in its constructor, the same instance is injected the revoled type.

Steven
  • 166,672
  • 24
  • 332
  • 435
  • Unfortunately when supporting other frameworks sometimes you're forced to make compromises including the use of an anti-pattern. This really doesn't help to answer the question at hand though. As I have no control over the object being created I cannot simply resolve the type and then set the property. The specified type needs to be injected into the constructor at the time the instance is created. – Dan Siegel Jan 24 '17 at 02:53
  • 1
    The stackoverflow answer I referred to in this answer, shows how to solve this problem. If it doesn't, please describe why that presented method doesn't work. – Steven Jan 24 '17 at 05:46
  • Perhaps I'm just missing something here, but from the answer in the post you referenced you're registering a service that wasn't previously registered with the container. In this particular case we're resolving a service that was registered with a Transient lifestyle, doing something to that instance then we need to inject that specific instance IF it's required by the type we want to resolve. I understand it's a less than ideal pattern, but it's one that I have to adopt in this particular case. – Dan Siegel Jan 24 '17 at 21:35
  • Singleton simply won't work. I suppose a scoped instance could work but I would need the scope to exist within the confines of that function. so if that code was in some function `public void DoFoo() { ... }` how would I go about getting the Scope to exist for that one function so when I call it in DoFoo I get an entirely new instance, and that instance gets injected when I resolve my type, and the next time I enter that block of code I get an entirely new instance to work with? – Dan Siegel Jan 25 '17 at 23:57
  • I was looking the [docs](http://simpleinjector.readthedocs.io/en/latest/lifetimes.html#per-execution-context-scope-async-await) on using the Scopes and what it shows really seems like it could work, but it looks like I need to install the `Execution Context Extensions NuGet package`, but this doesn't seem to be compatible with a Profile 259 PCL – Dan Siegel Jan 26 '17 at 03:06
  • @DanS try the LifetimeScopeLifestyle. – Steven Jan 26 '17 at 05:43