2

I have a Container that registers a Presenter class for a View:

Container.Register<ListCellPresenter>();

The Presenter's constructor takes one argument for its view:

public ListCellPresenter(ListCellView view) {
     this.view = view;
}

And I have a View that resolves an instance of the Presenter, passing itself as the argument for the constructor:

Container.Resolve<ListCellPresenter>(new object[] {this});

On the home screen I have multiple instances of this View, which each need their own instance of the Presenter. That part works.

However, it seems that DryIoc continually reuses the first object it received at runtime to satisfy the argument for the constructor. Each new instance of the Presenter receives the first instance of the View when the desire is that they should each receive unique instances.

I have tried various combinations of examples I've found in the docs including:

  • Registering with RegisterDelegate where the delegate explicitly uses Args.Index<ListCellView>(0) to satisfy the dependency
  • Registering with a standard Register using Made.Of(() => new ListCellPresenter(Arg.Of<ListCellView>())
  • Resolving with var getPresenter = Container.Resolve<Func<ListCellView, ListCellPresenter>>(); followed by presenter = getPresenter(this);

Any tips or guidance would be appreciated.

alphonzo79
  • 938
  • 11
  • 12
  • Can you double check if you pass different arguments each time? – opewix Jan 10 '19 at 23:01
  • @opewix Yes, this happens in an instance method of the View and I have logged out the hash code in the view right before trying to resolve the presenter. In the logging I see that I do, in fact, have multiple instances of the View. So I'm relatively confident that each call that passes `new object[] {this}` into the `Resolve` call is passing the unique instance. – alphonzo79 Jan 10 '19 at 23:13
  • @opewix I am using a single Container, delivered via a static factory, if that makes a difference. – alphonzo79 Jan 10 '19 at 23:14

2 Answers2

2

The problem is indeed a bug, and have been fixed in the newest preview versions: https://github.com/dadhi/DryIoc/issues/29

dadhi
  • 4,807
  • 19
  • 25
1

I found that opening named scopes does what you need.

var container = new Container();
container.Register<TargetClass>();
using (var scope = container.OpenScope("View_1"))
{
    var instanceA = scope.Resolve<TargetClass>(new[] { typeof(string) });    
}

using (var scope = container.OpenScope("View_2"))
{
    var instanceB = scope.Resolve<TargetClass>(new[] { typeof(int) });
}
opewix
  • 4,993
  • 1
  • 20
  • 42
  • interesting. I wondered if that would be the way to go. I am already within a named scope that has been opened for the individual screen. But you're saying that I should open an individual scope for each instance of the `ListCellView`? If that's the case, is there much cost to opening so many scopes since there are meant to be many of these views? If there is little to no cost, then this is an easy solution – alphonzo79 Jan 10 '19 at 23:42
  • Correct, new scope before resolving `ListCellPresenter`. Looks like the scoped container will re-create all or particular non-singleton dependencies on the first request and it seems you are the only one who can estimate the cost of that. Documentation may provide more technical details – opewix Jan 10 '19 at 23:48
  • 1
    that does, indeed solve my issue. It's in interesting way to accomplish it. I'll accept the answer for now, but I would like to see if there's a solution that uses the specific parameter passed in without need for the additional scoping. – alphonzo79 Jan 11 '19 at 00:01