sayo9394
sayo9394

Reputation: 485

C# Interface class and object dependencies AND design issue (code separation)

First day on the job I got handed down guy's code who is no longer at the company. An intern got his hands on the code before I did and really did a number on it! So here is the situation.

Project A

namespace A{
    public class Evil { ... }
    public interface A1 { 
        Evil[] Evils
        {
            get;
            set;
        } 
        Evil getSomeEvilValue();
    }

    public class Hello : A1{
        public void some_func(){
            // reference to Project B 
            B.World w = new B.World();  // <--- Dependency on B!! Thank you intern!
            w.Run();
        }

        #region A1 implementation
        Evil[] evils;
        Evil[] Evils
        {
            get{return evils;}
            set{evils = value;}
        } 
        Evil getSomeEvilValue(){return new Evil();}
        #endregion
    }  
}

in another project B

Project B
    namespace B{
    public class World{
        public void Run(){
            ...
        }
    }  
}

New requirements specify that Project B has to interface with A1!! This will create circular reference! So I thought the solution will be by creating a 3rd project, Interfaces, and changing A and B to reference the new one.

But the question is how do I deal with the A1's dependencies on class Evil??

Project Interfaces
namespace Interfaces
{
    public interface A1
    {
        Evil[] Evils   // <---- what do i do here?? IEvil? 
        {
            get;
            set;
        } 
        Evil getSomeEvilValue();  // <----- What do i do here???
    }
 }

Thanks heaps for your help guys!

Upvotes: 1

Views: 195

Answers (1)

MrWombat
MrWombat

Reputation: 649

Use Inversion of Control

  1. Extract the interfaces to a project that A and B know -> AB-Interfaces

  2. Create a Project that is the entry point for the application, it stands for the so called "Composition root" - here you reference A and B and you pass the references to the classes (so B would request A in the constructor, as property,...) and A would request B (not also in the constructor otherwise you will have a circular dependency again ;)

You could also do this with a DI controller but for now this would do it.

See a code example here.

In your code:

Project A
namespace A {
        public class Hello : A1{
            public Hello(IWorld world){
                w.run(this);
            }
    }
}

Project B
namespace B {
    public class World : IWorld {
        public run(A1 a1){
            ...
        }
    }
}

Project I
namespace I {
    public interace A1{}
    public interface IWorld { run(A1); }
}

project Comp
namespace Comp {
    public class AppEntry {
        IWorld w = new World();
        A1 a1 = new Hello(w);
    }
}

Upvotes: 4

Related Questions