1

I have a Parent object which looks like this (pseudocode):

class Parent {
  String token;
  Child[] children;
}

It contains a token string and an array of Child objects. My problem is that each of these Child objects needs to access the token string from the Parent class.

My first hunch is to loop through the children and specifically set a reference to the Parent object. Is there a more recommended way to take care of this, or is this kind of coupling unavoidable? I'm working in C# specifically but would be interested in any language-agnostic solutions as well.

2
  • 2
    IF you want a reference to the parent class in each child, then the children shouldn't be an array of the parent, but rather contained elsewhere. Commented Apr 16, 2019 at 22:50
  • 2
    In general this should be avoided. The token should be passed down to children, or picked up by an accumulator/visitor that is walking your tree.
    – Telastyn
    Commented Apr 16, 2019 at 23:44

2 Answers 2

2

A reference to the parent in the child is one method. Another is (if the child's methods are being called by the parent) to pass the parent (or just the token) as a parameter where it's needed.

Factors that could affect the decision:

  • Is Parent mutable or immutable? Same question for Child.
  • Do children ever change parents, or is it fixed once constructed?
  • Are children ever shared between multiple parents?
3
  • Hi, thanks for the response! Parents and children are both mutable using methods contained in the Parent and Child respectively. Children never change parents. That is fixed once constructed although Parents can gain additional Children or destroy Children. Also, Children are never shared between Parents. We've thought of removing the Child class entirely and encapsulating all of this directly into the Parent, but having that class makes our deserialization so much easier.
    – Tim Clancy
    Commented Apr 17, 2019 at 1:35
  • Also the child's methods are not being called through the parent.
    – Tim Clancy
    Commented Apr 19, 2019 at 3:15
  • In that case, setting a reference to the parent in the children seems like a reasonable way to do it. It's coupling, but it's coupling that would already be present, and not all coupling is a bad thing.
    – Errorsatz
    Commented Apr 19, 2019 at 17:49
0

Depends on the problem. But scoped service containers can help here.

var serviceProvider = new ServiceCollection()
   .AddScoped<ITokenProvider, TokenProvider>()
   .AddTransiant<ISomething, ISomethingOne>()
   .AddTransiant<ISomething, ISomethingTwo>()
   .AddTransiant<ISomeUnitOfWork, SomeUnitOfWork>()
   .BuildServiceProvider();

using (var scope = serviceProvider.CreateScope())
{
   await scope.ServiceProvider.GetService<ISomeUnitOfWork>().Work();
}

Since ITokenProvider is scoped all services will get the same instance during the same scope.

So 

public class SomeUnitOfWork : ISomeUnitOfWork
{
   public SomeUnitOfWork(ITokenProvider tokenProvider, IEnumerable<ISomething> somethings)
   {
      this.tokenProvider = tokenProvider;
      this.somethings = somethings;
   }

   public Task Work() 
   {
      tokenProvider.SetToken("Foobar"); //This can be done anywere in the lifetime of the scope
      return somethings
         .Select(s => s.Execute())
         .WhenAll();
   }
}

public class SomethingOne : ISomething
{
   public SomethingOne(ITokenProvider tokenProvider) 
   {
      this.tokenProvider = tokenProvider;
   }

   public Task Execute() 
   {
      //TODO: Do some work
   }

}

Scopes are a really powerful tool in a large system. For example in a frontend each window can have its own scope. And events will be fired between components in the window them using a scoped event aggregator.

Some more info on my blog (Not using AspNetCore DI so a bit outdated) https://andersmalmgren.com/2015/06/23/abstract-di-container-scopes/

1
  • Thank you for sharing all of this, but I'm having a pretty hard time grokking this. I'm not sure how this would be different than writing something like an entire messaging/event system routed through a third class just to fetch the access token from the Parent.
    – Tim Clancy
    Commented Apr 19, 2019 at 5:37

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.