komodosp
komodosp

Reputation: 3658

C# Accessing a class from a "parent project" in a "child project"?

Let's say I have multiple projects within a solution. I have the main project parent_project and another project child_project.

How can I access classes / namespaces residing in parent_project from child_project ?

I have already added a Reference to child_project in parent_project so I can't add a Reference to parent_parent in child_project as it would create a circular dependency.

Is this possible?

Upvotes: 5

Views: 3963

Answers (6)

Devbrat Raghuvanshi
Devbrat Raghuvanshi

Reputation: 27

Ok so let's say you have a Project with 2 solution in it S1 and S2 and you have reference S1 in S2, inside S1 it you have a class P and in S2 you have three Class defined by user A B an C. now make A inherit P so when you invoke constructor of A it will invoke constructor of P (that's in In S1) noe inside P's Constructor if you want the list of all the class declared in S2 use this code.

    Assembly assembly = this.GetType().Assembly;

    // DefinedTypes will list all Userdefined class
    foreach (var typeInfo 
 inassembly.DefinedTypes ) 
    {
      // typeInfo.FullName //you will have  A B and C
    }

Upvotes: -1

Hitesh
Hitesh

Reputation: 121

I didn't require entire namespace, but just reading some data dictionary or calling one particular method from parent project class. Here is how we got it working.

using System;
using NUnit.Framework;
using System.Collections.Concurrent;

namespace MyProject.tests
{
    public class ParentChildTest
    {
        [Test]
        public void dataAndMethodTest()
        {
            // add the data in parent project
            Parent.propertyCache["a"] = "b";

            // read the data in child project
            Console.WriteLine("Read from child: " + Child.getProperty("a"));

            // use Child project to call method of parent project
            Console.WriteLine("Call from child: Populate method in parent: " + Child.populate("c"));
        }
    }

    class Parent
    {
        // data is in Child project. Parent project just has the reference.
        public static ConcurrentDictionary<string, string> propertyCache = Child.getPropertyCache();

        public static string populate(string key)
        {
            //calculation
            string value = key + key;
            propertyCache[key] = value;
            return value;
        }

        // Pass the parent project method reference to child project
        public static int dummy = Child.setPopulateMethod(populate);
    }

    class Child
    {
        // data store
        static ConcurrentDictionary<string, string> propertyCache = new ConcurrentDictionary<string, string>();

        public static ConcurrentDictionary<string, string> getPropertyCache()
        {
            return propertyCache;
        }

        public static string getProperty(string key)
        {
            if (propertyCache.ContainsKey(key))
            {
                return propertyCache[key];
            }
            return null;
        }

        // reference to parent project method
        static Func<string, string> populateMethodReference = null;

        public static int setPopulateMethod(Func<string, string> methodReference)
        {
            populateMethodReference = methodReference;
            return 0;
        }

        public static string populate(string key)
        {
            return populateMethodReference(key);
        }
    }
}

Using parent project class data in child

  1. Earlier the propertyCache was in parent class. Child needed to access it.
  2. So, the propertyCache has been moved to Child. Parent also reads and populates the same.

Using parent project class method in child

  1. Pass the method reference to the child somehow (by some static method).
  2. use the reference to invoke that parent method.

Output of the program

Read from child: b
Call from child: Populate method in parent: cc

Upvotes: 1

komodosp
komodosp

Reputation: 3658

FYI

I ended up just copying the logic to a shared location, and "child" projects can access this version. I know from a maintainability point of view this isn't the best solution but it seemed like the best compromise..

Upvotes: 1

Paddy
Paddy

Reputation: 33877

You can inject your dependency using an interface defined in the child project (this can be useful where major refactoring is not possible/too expensive).

e.g. In the child project:

interface IA {
   DoLogicInB();
}

In the parent project:

class ConcreteA : ChildProject.IA
{
    DoLogicInB() { ... }
}

In the child project, where you need the logic:

class ChildB {
   void DoSomethingWithParent(IA logicEngine) {
       logicEngine.DoLogicInB();
   }
}

You need to then be able to inject a concrete implementation of the parent object from outside the child project.

Upvotes: 2

Thomas
Thomas

Reputation: 2984

I have to say that Yannicks answer is the way to go there normally. In your special situation (as outlined in your comment to his answer) it sounds like that would be problematic. A different way would be (only possible if the mainclass compiles into a dll):

  • Include the compiled dll of the mainproject in the child project
  • Use the methods you need via reflection

This is one possible other route BUT has quite a few pitfalls as reflection has troubles of its own.

Upvotes: 0

Yannick Meeus
Yannick Meeus

Reputation: 5910

If you're sharing logic between projects, you need to isolate that dependency and move it to a shared location (new project for example), restructure your dependencies so that your core logic lives in a core domain-like project or mash your projects together.

The latter is not really the cleanest of solutions. I would recommend thinking about your own question and really try to answer "Why do I NEED a circular reference? How can I restructure so that my dependencies make sense?".

Upvotes: 10

Related Questions