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

Resolve caches object[] args values #29

Closed
kirodge opened this issue Oct 5, 2018 · 11 comments
Closed

Resolve caches object[] args values #29

kirodge opened this issue Oct 5, 2018 · 11 comments

Comments

@kirodge
Copy link
Contributor

kirodge commented Oct 5, 2018

Hi,

I'm not sure if this is a issue or by design.
I am trying to create a ViewModel-factory

public class ViewModelFactory
{
        private readonly IResolver _resolver;
        public ViewModelFactory(IResolver resolver)
        {
            _resolver = resolver;
        }

        public T CreateViewModel<T>(params object[] args)
        {
            return (T)_resolver.Resolve(typeof(T), args);
        }
}

On the first call to CreateViewModel with a System.Guid as parameter

var editViewModel = _viewModelFactory.CreateViewModel<IEditViewModel>(guidId);

everything works as expected. The constructor of the registered EditViewModel is run with the provided guidId, and other parameters injected. However on a second call

var editViewModel = _viewModelFactory.CreateViewModel<IEditViewModel>(anotherGuidId);

the guid-value from the first call is injected to the constructor again.

It seems to me that DryIoc's Resolve caches object[] args values.
Is this intended?

I'm aware that I can use

var getter = _resolver.Resolve<Func<Guid,T>>();
getter(guidId)

but not all of my viewmodels require a guid as parameter. Some require no guid, some require two, and some might require other values only known at runtime.

Thanks for any advice

@dadhi
Copy link
Owner

dadhi commented Oct 5, 2018

@kirodge, Thanks for posting.

Yes, it is probably a cache, but it should not be there because of arguments. I will check.

@kirodge
Copy link
Contributor Author

kirodge commented Oct 5, 2018

Thanks, I created a PR for testing the issue

dadhi pushed a commit that referenced this issue Oct 5, 2018
@dadhi
Copy link
Owner

dadhi commented Oct 5, 2018

The fix is available in DryIoc v3.1.0-preview-03

@kirodge
Copy link
Contributor Author

kirodge commented Oct 5, 2018

Thanks a lot for the quick fix @dadhi.
The issue is resolved in DryIoc v3.1.0-preview-03

@kirodge kirodge closed this as completed Oct 5, 2018
@kirodge
Copy link
Contributor Author

kirodge commented Oct 25, 2018

@dadhi Set milestone 3.1.0?

@dadhi
Copy link
Owner

dadhi commented Oct 25, 2018

yep.

@kirodge
Copy link
Contributor Author

kirodge commented Jan 16, 2019

I would set milestone myself, if I was able to.

Any due date for 3.1?

@dadhi
Copy link
Owner

dadhi commented Jan 16, 2019

It will be a v4. Currently in a preview. Soonish I hope.

@Leszek-Kowalski
Copy link
Contributor

This issue is a show stopper for my project as well.
Any timelines for v4 ?
Maybe it could be back-ported to 3.1 in the mean time ?
Thanks.

@dadhi
Copy link
Owner

dadhi commented Feb 18, 2019

V4 will be here soon. If you are watching the repo, you see that I am closing the last bugs.

Regarding back ports, I am open for PRs.

@rdeago
Copy link
Contributor

rdeago commented Apr 1, 2019

EDIT: Actually, it appears to be another issue. Please see #105.


It appears that the issue is still there in v4.0.1.

I've prepared the tiniest use case I could come up with and placed it in a .NET fiddle.

Here's the code, for completeness:

// @nuget: DryIoc.dll -Version 4.0.1

using System;
using DryIoc;

public class Program
{
	public static void Main()
	{
		using (var container = new Container(ConfigureContainer))
		{
			container.Register<IAlpha, Alpha>();
			container.Register<IBravo, Bravo>();
			
			using (var scope = container.OpenScope())
			{
				Console.WriteLine("--- Scope #1");
				scope.ResolveNamed<IAlpha>("Alice");
				scope.ResolveNamed<IBravo>("Bob");
			}
			
			using (var scope = container.OpenScope())
			{
				Console.WriteLine("--- Scope #2");
				// I would expect the Container to throw on the following line,
				// because it doesn't know how to create an instance of Alpha.
				// Instead, it happily creates an Alpha named Bob!
				scope.ResolveNamed<IBravo>("Bob");
			}
		}
	}
	
	static Rules ConfigureContainer(Rules rules)
	{
		return rules
            .With(FactoryMethod.ConstructorWithResolvableArguments)
            .WithDefaultReuse(Reuse.ScopedOrSingleton);
	}
}

public static class ResolverExtensions
{
	public static TService ResolveNamed<TService>(this IResolver @this, string name)
	{
		return @this.Resolve<TService>(args: new object[] { name });
	}
}

public abstract class Service
{
	protected Service(string name)
	{
		Console.WriteLine("This is an instance of {0} called {1}.", GetType().Name, name);
	}
}

public interface IAlpha { }

public interface IBravo { }

public sealed class Alpha : Service, IAlpha
{
	public Alpha(string name)
		: base(name) { }
}

public sealed class Bravo : Service, IBravo
{
	public Bravo(string name, IAlpha alpha)
		: base(name) { }
}

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

4 participants