Code to check the circular dependency between classes

Hitesh Maheshwari 1 Reputation point
2021-04-28T18:32:24.847+00:00

**Circular dependency between classes

I've tried something this works well, it needs to be checked whether it's correct or if anyone can help me with it.**

public static class EntitySerializerHelper
    {
        private const byte MaxNumberStackTraceFrameCount = 100;
        public static void HasCircularDependency(this Type entityObjectType)
        {
            CheckStackDepth();

            var publicProperties = entityObjectType.GetProperties()
                .Where(o => o.PropertyType.IsPublic && !o.PropertyType.IsValueType && o.PropertyType != typeof(string)).ToArray();

            foreach (var propertyInfo in publicProperties)
            {
                var typeOfObject = propertyInfo.PropertyType;

                if (typeOfObject.IsGenericType)
                {
                    if (HasTypeDictionary(typeOfObject))
                    {
                        var keyType = typeOfObject.GetGenericArguments()[0];
                        var valueType = typeOfObject.GetGenericArguments()[1];

                        HasCircularDependency(keyType);
                        HasCircularDependency(valueType);
                    }
                    else if (HasEnumerableType(typeOfObject))
                    {
                        var itemType = typeOfObject.GetGenericArguments().Single();
                        HasCircularDependency(itemType);
                    }
                }
                else if (typeOfObject.IsClass)
                {
                    HasCircularDependency(typeOfObject);
                }
            }
        }

        static void CheckStackDepth()
        {
            if (new StackTrace().FrameCount > MaxNumberStackTraceFrameCount)
            {
                throw new StackOverflowException("StackOverflow");
            }
        }

        static bool HasEnumerableType(Type type)
        {
            if (type.IsInterface && type.GetGenericTypeDefinition() == typeof(IEnumerable<>))
            {
                return true;
            }

            foreach (var intType in type.GetInterfaces())
            {
                if (intType.IsGenericType && intType.GetGenericTypeDefinition() == typeof(IEnumerable<>))
                {
                    return true;
                }
            }

            return false;
        }

        static bool HasTypeDictionary(Type typeOfObject)
        {
            return typeOfObject.GetGenericTypeDefinition() == typeof(Dictionary<,>);
        }
    }
Developer technologies C#
{count} votes

1 answer

Sort by: Most helpful
  1. Timon Yang-MSFT 9,606 Reputation points
    2021-04-29T09:43:23.65+00:00

    Try the following code:

    class Program  
        {  
            static void Main(string[] args)  
            {  
                Type type = typeof(A);  
                Type type2 = typeof(B);  
                var c1 = type.GetProperties(BindingFlags.Public | BindingFlags.Instance).Where(t=>t.PropertyType == type2);  
                var c2 = type2.GetProperties(BindingFlags.Public | BindingFlags.Instance).Where(t=>t.PropertyType == type);  
      
                if (c1.Count()!=0 && c2.Count()!=0)  
                {  
                    Console.WriteLine("They are circularly dependent");  
                }  
            }  
        }  
        public class A  
        {  
            public B TypeB { get; set; }  
        }  
      
        public class B  
        {  
            public A TypeA { get; set; }  
        }  
    

    Did I understand what you mean correctly?

    Update:

    You said that they are the relationship between the parent type and the child type, but the above example does not seem to reflect this relationship.

    If they have an inheritance relationship, then even if we don't know the exact type of the subclass, we should be able to put it in the collection of the parent class, and then use reflection to get the exact type and get all the properties.

        class Program  
        {  
      
            static void Main()   
            {  
                List<A> classes = GetA();  
                foreach (var item in classes)  
                {  
                    Console.WriteLine(item.GetType());  
                }  
                Console.WriteLine("Press any key to continue...");  
                Console.ReadLine();  
            }  
            public static List<A> GetA()   
            {  
                List<A> classes = new List<A>();  
                classes.Add(new A());  
                classes.Add(new B());  
                classes.Add(new C());  
                return classes;  
            }  
        }  
      
        class A  
        {  
            public B TypeB { get; set; }  
        }  
        class B:A  
        {  
            public C TypeC { get; set; }  
        }  
        class C:B  
        {  
            public A TypeA { get; set; }  
        }  
    

    If the response is helpful, please click "Accept Answer" and upvote it.
    Note: Please follow the steps in our documentation to enable e-mail notifications if you want to receive the related email notification for this thread.


Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.