StackOverFlow in the implementation of the Dependency Inversion Principle for cross-refenced classes

做~自己de王妃 提交于 2020-06-01 07:03:40

问题


The Situation:

I have three classes: Society, Father and Son. The Society has a list of Fathers. Each Father has one son. It is necessary in this application that each Father knows who his Son is and vice-versa each Son knows who his Father is.

I have used direct cross referencing by assigning the Father as a property of the Son, and the Son as a property of the Father class, as below:

public class Society : ISociety
{
    public List<IFather> Fathers {get; set;}
}


public class Father : IFather
{
    public Father(ISon inp_son)
    {
       MySon = inp_son; 
    }

    public ISon MySon {get; set;} 
}


public class Son : ISon
{
    public Son(IFather inp_father)
    {
       MyFather = inp_father;  
    }

    public IFather MyFather {get; set;}
}

To manually implement dependency inversion, I have a public static class called Factory. The Factory returns interfaces of the Society, Father and Son classes through its methods. The methods instantiate Society, Father and Son classes and return them respectively as ISociety, IFather and Ison.

public static Factory
{
    public static IFather CreateFather()
    {
        return new Father(CreateSon());
    }


    public static ISon CreateSon()
    {
        return new Son(CreateFather());
    }
}

The application runs as follows.

.
.
.
     IFather Father = Factory.CreateFather();
     Society.Fathers.Add(Father);      
.
.
.

The proeblem:

Every time the factory creates a Father, it instantiates a Son as its constructor input by invoking the CreateSon() method. When the CreateSon() method creates a Son, it invokes the CreateFather() method. This causes an endless loop, resulting in the StackOverFlow problem.

The big picture:

I have a large class library. In my library, higher-level classes have lists of lower-level classes. Calculations are performed inside the lower-level classes. The calculations need to access the properties of the higher-level classes. Therefore, the calculations need to somehow find their way to the higher level classes through the low-level class they belong to.

To be able to unit-test the code, I need to instantiate the Son class by passing the Factory.CreateFather() in to the constructor of the Son.cs class. Doing so allows me to swap out the Father class with say Mother class in the Factory class without breaking the code.

I don't know of a more elegant way to allow the Son to know who the Father is other than these two ways:

1- The above-mentioned approach, which is cross referencing by directly assigning the MyFather property of the son.

2- Saving an identifier property of the Father (int number or Guid) in the Son. So the son can search for the Father by: Father MyFather = Society.Fathers[MyFathersNumber]. Given the list of Fathers is controlled not to have duplicates. The problem with this approach is that in a long chain of hierarchy, accessing a class several layers up becomes a difficult navigation and a lengthy line of code.

I had previously moved from way-2 to way-1 as a cleaner approach in the absence of dependency inversion. Now I am having StackOverFlow problem when I combine way-2 with the DI principle.

My Question:

Can someone please tell me what is the elegant way to let the Son know who his father is without causing a conflict with the Dependency Inversion Principle?

Thank you.

来源:https://stackoverflow.com/questions/61794493/stackoverflow-in-the-implementation-of-the-dependency-inversion-principle-for-cr

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!