The following class diagram is a simplified version of a project I'm working on.

The class A is responsible for serializing/deserializing the graph of objects rooted at C. I'm using Csharp's framework for serialization so when I deserialize the class C, the framework creates a new instance of all in objects rooted at C (shown in the diagram by the *new classes). Now I'd like to replace A's instance of C with Cnew but the problem is that B1 and B2 still point to the old D1 and D2. It would be nice to not have to reinitialize B2 and B2's dependencies.
I am looking for a way to have B1 and B2 be able to access D1 and D2 through A without giving them access to C or to each other. For simplicities sake we can assume that all of A's members have to be public (It implements an interface from a framework I'm using that forces a lot of members to be public).
Here are some potential solutions I though of:
Just bite the bullet and reinitialize B1 and B2
Give B1 and B2 a references to A instead of D1 and D2 and just ignore the fact that this gives them access to a lot of classes they don't need access to.
Instead of giving the B classes direct access to the D classes have A pass in delegates (function pointers) for functions that return A's instance of D1 and D2.
Have A implement interfaces like D1Container and D2Container that have 1 required method which returns an instance to D1 or D2. Then cast A to D1Container or D2Container and pass it to B1 and B2.
Is there a design pattern for this sort of thing or is one of my solutions clearly the best?
Thanks!
You are looking to introduce another level of indirection in your design: essentially, instead of storing a reference to D1 and D2 you are looking to store something that would let you get the most current D1 and D2. Your #3 (delegate) option stands out as the most elegant to me, because you do not need to introduce new classes to implement delayed evaluation. All you need is a Func<D> that A passes to B - no new classes, interfaces, or delegates; everything remains nicely encapsulated.
class A {
private B myB;
private C myC;
public A() {
myC = new C();
myB = new B(() => myC.MyD);
}
}
class B {
private readonly Func<D> getD;
public B(Func<D> getD) {this.getD = getD;}
public D { get { return getD(); } }
}
class C {
public D MyD {get; private set;}
}
Now if A changes its C, or C changes its D, B.D would continue returning the correct D automatically. This is because under the hood, B holds a reference to A, but it has no idea that it does.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With