What is the appropriate architecture to access variable in parent from element of child list?
https://softwareengineering.stackexchange.com/questions/390472
-
23-02-2021 - |
Question
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.
Solution
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?
OTHER TIPS
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/