Skip to content
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

Call kernel.Get<T> two times do not give the same result #262

Closed
Xebast opened this issue Nov 21, 2017 · 4 comments
Closed

Call kernel.Get<T> two times do not give the same result #262

Xebast opened this issue Nov 21, 2017 · 4 comments
Assignees
Milestone

Comments

@Xebast
Copy link

Xebast commented Nov 21, 2017

Ninject Version : Current Release (Version 3.2)

In sample application below, we want to verify that multiple call to Get give the same result : throw Activation Exception - because we did not bind any IWeapon object - .

image

The first call is OK, exception is raised (visualized in Text Visualizer) :

image

Unfortunnately, the second call does not throw exception and return an instance of Samurai.
This is not what we expect.
We check that Context class uses Cache for Resolution :

  • that stores an instance, created during the first call of Get (cache.Remember(this, reference)
    (Cache is not cleared, even if ActivationException occurs after)
  • that returns this instance during second call :

image

This behavior is strange (same method Get called twice gives different result), but maybe we are wrong in our expected result ? Or Maybe we have to modify Ninject Setting ? (We turned ActivationCacheDisabled to True, but no impact)
image

Note : same behavior in pending V4 version.

Someone could help ?
Thanks.

@BrunoJuchli
Copy link
Contributor

Could you provide the code for "copy & paste" so we can easily reproduce the issue?

@BrunoJuchli
Copy link
Contributor

To summarize the issue:

When a Type (Samurai) is bound InSingletonScope() and uses property injection, and this property fails to inject, then a second call to Get<Samurai> will return a Samurai instance with uninitialized property.

The expected outcome would be to throw the same ActivationException (and, internally, not having cached the Samurai instance).

@Xebast
Copy link
Author

Xebast commented Nov 22, 2017

You perfectly summarized the topic and the expected outcome.

Here is sample code :

public void TestNotRequiredHelloWorld()
{
	string exceptionMessage = string.Empty;
	var ninjectSettings = new NinjectSettings() { AllowNullInjection = true };
	var kernel = new StandardKernel(ninjectSettings);

	//No Weapon defined in our Program
	//kernel.Bind<IWeapon>().To<Sword>().InSingletonScope();

	kernel.Bind<Samurai>().ToSelf().InSingletonScope();

	Samurai samurai1;
	try
	{
		//So that I expect to have exception during resolution
		samurai1 = kernel.Get<Samurai>();
	}
	catch (Exception e)
	{
		//Yes, I have expected activation exception
		exceptionMessage = e.Message;
	}

	//I try Again...
	//Here, NO EXCEPTION and a Samurai is retrieved with Weapon to null
	//And it is not the expected result
	Samurai samurai2 = kernel.Get<Samurai>();
}

class Samurai
{
	[Inject]
	public IWeapon Weapon { get; set; }

	public Samurai() { }
}

class Sword : IWeapon
{
	public Sword() { }

	public void Hit() { Console.WriteLine("Sword"); }
}

interface IWeapon
{
	void Hit();
}

@Xebast
Copy link
Author

Xebast commented Nov 23, 2017

Hi BrunoJuchli and scott-xu,
Thank you for your quick feedback and fix !

@scott-xu scott-xu self-assigned this Apr 12, 2022
@scott-xu scott-xu added this to the 3.3.5 milestone Apr 12, 2022
scott-xu added a commit that referenced this issue Apr 12, 2022
glenkeane-94 pushed a commit to glenkeane-94/Nin-ject that referenced this issue Jun 17, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants