Search code examples
c#.netsolid-principlesvisitor-patterncyclic-dependency

Cyclic depenency: IVisitor and Datas


I recently asked about cyclic dependency. The answer was to dedicate a project on interfaces (MyProject.Abstractions). Now, this project is the cause of another cyclic dependency, with a Visitor pattern.

namespace MyProject.Abstractions
{
    public interface ICharacter { }

    public interface ICharacterVisitor
    {
        // References MyProject.Characters
        void Visit(Warrior warrior);
        void Visit(Wizard wizard);
    }
}

namespace MyProject.Characters
{
    // References MyProject.Abstractions
    public abstract class CharacterBase : ICharacter { }

    public class Warrior : CharacterBase { }
    public class Wizard : CharacterBase { }
}

Does it mean that my ICharacterVisitor should be in my MyProject.Characters project ? I dedicate this entire solution to be my SOLID training exercice.


Solution

  • The visitor is a tool that applies to an existing structure but is not a part of it. Therefore I would separate the visitor from the data you are visiting.

    namespace MyProject.Abstractions.Characters
    {
        public interface ICharacter { }
    }
    
    using MyProject.Abstractions.Characters;
    
    namespace MyProject.Characters
    {
        public abstract class CharacterBase : ICharacter { }
    
        public class Warrior : CharacterBase { }
        public class Wizard : CharacterBase { }
    }
    
    using MyProject.Abstractions.Characters;
    using MyProject.Characters;
    
    namespace MyProject.Abstractions.Visitors
    {
        public interface ICharacterVisitor
        {
            // References MyProject.Characters
            void Visit(Warrior warrior);
            void Visit(Wizard wizard);
        }
    }
    
    using MyProject.Abstractions.Characters;
    using MyProject.Abstractions.Visitors
    using MyProject.Characters;
    
    namespace MyProject.Visitors
    {
        // Concrete visitors here
    }
    

    You don't necessarily need to have a separate project for each namespace. The visitor stuff could be in the same project as MyProject.Characters. SOLID is about a logical organization of code, not a physical. This answer to benefits of multiple Projects and One Solution lists good reasons for having multiple projects.