Wilbert
Wilbert

Reputation: 7399

Ninject context extraction from factory parameter

I have an object that defines a scope:

Bind<ISomething>().To<Something>().DefinesNamedScope(SomethingScope);

I also have a auto-generated factory that creates IAnotherThing:

public interface IAnotherThingFactory
{
   IAnotherThing CreateAnotherThing(ISomething x);
}

And bind it:

Bind<IAnotherThingFactory>().ToFactory();

I would like to create the IAnotherThing in the context of ISomething, so I can e.g. have a ISharedPrivateDependency that both get the same instance of. However, Something must not be aware of IAnotherThing. That means that, ideally, there should be a way to extract the context from the ISomething parameter, and use it to set the context for IAnotherThing.

What binding do I have to define or code to write in order to get this behavior?

I do not want to expose the kernel directly, only the factory.

Edit after comments:

Upvotes: 1

Views: 239

Answers (1)

BatteryBackupUnit
BatteryBackupUnit

Reputation: 13233

Have a look at ninject contextpreservation extension: https://github.com/ninject/ninject.extensions.contextpreservation/wiki

ISomething will need to provide the IAnotherThingFactory (p.Ex. as property) in order for the objects created by IAnotherThingFactory to use the same context as ISomething.

Hint: The scope of the factory can be relevant. If you define the factory .InSingletonScope it won't work, or rather, all objects created by the factory will have the same context as the object that first requested the factory.

In case you need it even more generic, what you can do is inject an IResolutionRoot into ISomething and provide it as property. Then someone can do ISomething.ResolutionRoot.GetContextPresreving<IFoo>(); or even ISomething.ResolutionRoot.GetContextPresreving<IAnotherThingFactory>().CreateAnotherThing();

If you don't want to reference ninject, what you can do is hide IResolutionRoot in a wrapper IFactory, like:

internal class Factory : IFactory {

    private readonly IResolutionRoot resolutionRoot;

    public Factory(IResolutionRoot resolutionRoot) {
        this.resolutionRoot = resolutionRoot;
    }

    T Create<T>() {
        return this.resolutionRoot.GetContextPreserving<T>();
    }
}

However i suggest that this can probably be solved by improving the design (in a larger scope). For us at least it was never necessary to do such a thing - even though we have the requirement of late creating objects in the same context as another object, while the creation is triggered from a different context.

Upvotes: 0

Related Questions