Code Comments

Programming Forum and web based access to our favorite programming groups.
For Programmers: Free Programming Magazines | New: Database administration forum
Registration is free! Edit your profileCalendarFind other membersFrequently Asked QuestionsSearch -> 
Post New Thread











Thread
Author

Circular dependency problem
Hi all,

I have the following problem: I have 2 namespaces: NamespaceA in
ProjectA, and NamespaceB in ProjectB. NamespaceA contains class ClassA,
which contains a field of type NamespaceB.ClassB. And the other way
around: NamespaceB contains ClassB, containing a field of type
NamespaceA.ClassB. The compiler gives an error saying, that I am missing
the assembly references. So I add ProjectB to the references of
ProjectA, and after that try to add ProjectA to the references of
ProjectB, which Visual Studio does not enable me to do, saying, that
there would be a circular depency. How can I solve this problem?

Regards,

Krzysztof Kozlowski

Report this thread to moderator Post Follow-up to this message
Old Post
Krzysztof Koz這wski
05-18-05 09:00 AM


Re: Circular dependency problem
You have to break the cycle using an interface. Where the interface
belongs depends upon what these classes are for, which is why I asked
that. However, in general, here is how you solve the problem.

NamespaceA defines an interface, IClassB, that defines which operations
of ClassB ClassA needs in order to survive. In effect, NamespaceA
defines a "demand interface" that says, "ClassA will work together with
any class that implements this interface." As I said, call it IClassB.

You then change all places in ClassA that refer to ClassB to refer to
IClassB instead. So, now your property in ClassA returns an IClassB,
not a ClassB. This is OK because IClassB is defined in ProjectA, and
really belongs with ClassA, because it's the contract that ClassA
requires of any class it's going to work with.

Now that you've done that, ClassA now no longer knows about ClassB
directly. It only knows that it will be working with some class,
somewhere, that implements IClassB.

Now you define ClassB as implementing IClassB and you're done. ClassB
can still refer directly to ClassA, because there is no reference from
ClassA to ClassB, so there's no circle.

For a more concrete example, assume that ClassA is a business layer
class (call it BusinessA) and ClassB is a data layer class (call it
DataB). In project A, you would define (along with BusinessA) an
interface called IDataA, which in effect says, "The BusinessA class can
work with any data layer class that implements these methods and
properties." BusinessA has a property called DataLayer that returns an
instance of IDataA:

public IDataA DataLayer
{
get { return this._dataLayer; }
}

Now you can write DataB in ProjectB. DataB knows about BusinessA
directly, and can instantiate and return instances of that class,
because there's no direct reference from ProjectA to ProjectB, so now
the reverse is OK. DataB implements IDataA:

public class DataB : IDataA
{
..
}

Of course, you don't have stick to just DataB. You might also have a
test version of the data layer, called TestDataC. You can make as many
data layers as you like, so long as they all implement IDataA.

Again, which layer should declare the interface and which should
implement it depends upon the exact nature of your two projects.


Report this thread to moderator Post Follow-up to this message
Old Post
Bruce Wood
05-18-05 09:00 AM


Re: Circular dependency problem
Krzysztof Koz這wski wrote:
> Hi all,
>
> I have the following problem: I have 2 namespaces: NamespaceA in
> ProjectA, and NamespaceB in ProjectB. NamespaceA contains class ClassA,
> which contains a field of type NamespaceB.ClassB. And the other way
> around: NamespaceB contains ClassB, containing a field of type
> NamespaceA.ClassB. The compiler gives an error saying, that I am missing
> the assembly references. So I add ProjectB to the references of
> ProjectA, and after that try to add ProjectA to the references of
> ProjectB, which Visual Studio does not enable me to do, saying, that
> there would be a circular depency. How can I solve this problem?
>
> Regards,
>
> Krzysztof Kozlowski

I believe you will have to contain the two objects in the same class
library. You can keep the separate namespaces and the circular class
reference. However, you should probably use some sort of lazy loading
technique and not load anything when the class is created or you may end
up in an infinite loop.

Example:

Create a dll and call it whatever...
Then create the first source file containing the first namespace.
(ClassA.cs)

using System;
using LibB;

namespace LibA
{
public class ClassA
{
LibB.ClassB classB = null;

public LibB.ClassB ClassB
{
get
{
if (classB == null)
{
// Here you would load or instantiate...
classB = new ClassB();
}
return classB;
}
set { classB = value; }
}

public ClassA()
{
}
}
}


Then in the same dll create the second source file with the second
namespace.
(ClassB.cs)

using System;
using LibA;

namespace LibB
{
public class ClassB
{
LibA.ClassA classA = null;

public LibA.ClassA ClassA
{
get
{
if (classA == null)
{
// Here you would load or instantiate...
classA = new ClassA();
}
return classA;
}
set { classA = value; }
}

public ClassB()
{
}
}
}

Report this thread to moderator Post Follow-up to this message
Old Post
Mephisto
05-18-05 09:00 PM


Re: Circular dependency problem
Krzysztof Koz這wski wrote:
> Hi all,
>
> I have the following problem: I have 2 namespaces: NamespaceA in
> ProjectA, and NamespaceB in ProjectB. NamespaceA contains class ClassA,
> which contains a field of type NamespaceB.ClassB. And the other way
> around: NamespaceB contains ClassB, containing a field of type
> NamespaceA.ClassB. The compiler gives an error saying, that I am missing
> the assembly references. So I add ProjectB to the references of
> ProjectA, and after that try to add ProjectA to the references of
> ProjectB, which Visual Studio does not enable me to do, saying, that
> there would be a circular depency. How can I solve this problem?
>
> Regards,
>
> Krzysztof Kozlowski

I believe you will have to contain the two objects in the same class
library. You can keep the separate namespaces and the circular class
reference. However, you should probably use some sort of lazy loading
technique and not load anything when the class is created or you may end
up in an infinite loop.

Example:

Create a dll and call it whatever...
Then create the first source file containing the first namespace.
(ClassA.cs)

using System;
using LibB;

namespace LibA
{
public class ClassA
{
LibB.ClassB classB = null;

public LibB.ClassB ClassB
{
get
{
if (classB == null)
{
// Here you would load or instantiate...
classB = new ClassB();
}
return classB;
}
set { classB = value; }
}

public ClassA()
{
}
}
}


Then in the same dll create the second source file with the second
namespace.
(ClassB.cs)

using System;
using LibA;

namespace LibB
{
public class ClassB
{
LibA.ClassA classA = null;

public LibA.ClassA ClassA
{
get
{
if (classA == null)
{
// Here you would load or instantiate...
classA = new ClassA();
}
return classA;
}
set { classA = value; }
}

public ClassB()
{
}
}
}

Report this thread to moderator Post Follow-up to this message
Old Post
Mephisto
05-18-05 09:00 PM


Re: Circular dependency problem
Krzysztof Koz這wski wrote:
> Hi all,
>
> I have the following problem: I have 2 namespaces: NamespaceA in
> ProjectA, and NamespaceB in ProjectB. NamespaceA contains class ClassA,
> which contains a field of type NamespaceB.ClassB. And the other way
> around: NamespaceB contains ClassB, containing a field of type
> NamespaceA.ClassB. The compiler gives an error saying, that I am missing
> the assembly references. So I add ProjectB to the references of
> ProjectA, and after that try to add ProjectA to the references of
> ProjectB, which Visual Studio does not enable me to do, saying, that
> there would be a circular depency. How can I solve this problem?
>
> Regards,
>
> Krzysztof Kozlowski


I believe you will have to contain the two objects in the same class
library. You can keep the separate namespaces and the circular class
reference. However, you should probably use some sort of lazy loading
technique and not load anything when the class is created or you may end
up in an infinite loop.

Example:

Create a dll and call it whatever...
Then create the first source file containing the first namespace.
(ClassA.cs)

using System;
using LibB;

namespace LibA
{
public class ClassA
{
LibB.ClassB classB = null;

public LibB.ClassB ClassB
{
get
{
if (classB == null)
{
// Here you would load or instantiate...
classB = new ClassB();
}
return classB;
}
set { classB = value; }
}

public ClassA()
{
}
}
}


Then in the same dll create the second source file with the second
namespace.
(ClassB.cs)

using System;
using LibA;

namespace LibB
{
public class ClassB
{
LibA.ClassA classA = null;

public LibA.ClassA ClassA
{
get
{
if (classA == null)
{
// Here you would load or instantiate...
classA = new ClassA();
}
return classA;
}
set { classA = value; }
}

public ClassB()
{
}
}
}

Report this thread to moderator Post Follow-up to this message
Old Post
Mephisto
05-18-05 09:00 PM


Re: Circular dependency problem
Krzysztof Koz這wski wrote:
> Hi all,
>
> I have the following problem: I have 2 namespaces: NamespaceA in
> ProjectA, and NamespaceB in ProjectB. NamespaceA contains class ClassA,
> which contains a field of type NamespaceB.ClassB. And the other way
> around: NamespaceB contains ClassB, containing a field of type
> NamespaceA.ClassB. The compiler gives an error saying, that I am missing
> the assembly references. So I add ProjectB to the references of
> ProjectA, and after that try to add ProjectA to the references of
> ProjectB, which Visual Studio does not enable me to do, saying, that
> there would be a circular depency. How can I solve this problem?
>
> Regards,
>
> Krzysztof Kozlowski


I believe you will have to contain the two objects in the same class
library. You can keep the separate namespaces and the circular class
reference. However, you should probably use some sort of lazy loading
technique and not load anything when the class is created or you may end
up in an infinite loop.

Example:

Create a dll and call it whatever...
Then create the first source file containing the first namespace.
(ClassA.cs)

using System;
using LibB;

namespace LibA
{
public class ClassA
{
LibB.ClassB classB = null;

public LibB.ClassB ClassB
{
get
{
if (classB == null)
{
// Here you would load or instantiate...
classB = new ClassB();
}
return classB;
}
set { classB = value; }
}

public ClassA()
{
}
}
}


Then in the same dll create the second source file with the second
namespace.
(ClassB.cs)

using System;
using LibA;

namespace LibB
{
public class ClassB
{
LibA.ClassA classA = null;

public LibA.ClassA ClassA
{
get
{
if (classA == null)
{
// Here you would load or instantiate...
classA = new ClassA();
}
return classA;
}
set { classA = value; }
}

public ClassB()
{
}
}
}


Report this thread to moderator Post Follow-up to this message
Old Post
Mephisto
05-18-05 09:00 PM


Re: Circular dependency problem
> I have the following problem: I have 2 namespaces: NamespaceA in ProjectA,
> and NamespaceB in ProjectB. NamespaceA contains class ClassA, which
> contains a field of type NamespaceB.ClassB. And the other way around:
> NamespaceB contains ClassB, containing a field of type NamespaceA.ClassB.
> The compiler gives an error saying, that I am missing the assembly
> references. So I add ProjectB to the references of ProjectA, and after
> that try to add ProjectA to the references of ProjectB, which Visual
> Studio does not enable me to do, saying, that there would be a circular
> depency. How can I solve this problem?
>
> Regards,
>
> Krzysztof Kozlowski
>

The only way to do this is to use interfaces in at least one of the
projects. I am not sure how this would ever work though.

ClassA
ItemB
ItemA
ItemB1
ItemA1
... for ever

This is a bad thing. It seems like you have a base set of information that 2
classes need. The fact that C# does not create the actual class right away
saves you from that, but somehow you have to tell the ItemB that you do not
want to create an ItemA when you create it in a parent ItemA.

The following would seem a more logical class layout.

ClassA - all the items and information ClassBChild will have to access (or
your ClassB in existing class)
ClassB - all the items and information ClassAChild will have to access (or
your ClassA in existing class)

ClassAChild
ClassB item
ClassBChild
ClassA item



Report this thread to moderator Post Follow-up to this message
Old Post
Lorad
05-20-05 08:57 PM


Re: Re: Circular dependency problem
quote:
Originally posted by Bruce Wood You have to break the cycle using an interface. Where the interface belongs depends upon what these classes are for, which is why I asked that. However, in general, here is how you solve the problem. NamespaceA defines an interface, IClassB, that defines which operations of ClassB ClassA needs in order to survive. In effect, NamespaceA defines a "demand interface" that says, "ClassA will work together with any class that implements this interface." As I said, call it IClassB. You then change all places in ClassA that refer to ClassB to refer to IClassB instead. So, now your property in ClassA returns an IClassB, not a ClassB. This is OK because IClassB is defined in ProjectA, and really belongs with ClassA, because it's the contract that ClassA requires of any class it's going to work with. Now that you've done that, ClassA now no longer knows about ClassB directly. It only knows that it will be working with some class, somewhere, that implements IClassB. Now you define ClassB as implementing IClassB and you're done. ClassB can still refer directly to ClassA, because there is no reference from ClassA to ClassB, so there's no circle. For a more concrete example, assume that ClassA is a business layer class (call it BusinessA) and ClassB is a data layer class (call it DataB). In project A, you would define (along with BusinessA) an interface called IDataA, which in effect says, "The BusinessA class can work with any data layer class that implements these methods and properties." BusinessA has a property called DataLayer that returns an instance of IDataA: public IDataA DataLayer { get { return this._dataLayer; } } Now you can write DataB in ProjectB. DataB knows about BusinessA directly, and can instantiate and return instances of that class, because there's no direct reference from ProjectA to ProjectB, so now the reverse is OK. DataB implements IDataA: public class DataB : IDataA { ... } Of course, you don't have stick to just DataB. You might also have a test version of the data layer, called TestDataC. You can make as many data layers as you like, so long as they all implement IDataA. Again, which layer should declare the interface and which should implement it depends upon the exact nature of your two projects.
Thanks Bruce for giving solution on circular dependency problem. Same proble m I got in c#.net of circular dependency. I have implement interface as you have told but still I have some problem. I have two projects projectA and Project B. Now I want to inherite Project A into Project B so I have given reference of Project A to Project B. Now I w ant call Project B methods from Project A so I have to give reference of Pro ject B to Project A but it create Circular Dependency. So I have create one interface in Project A with decalration of method which is in Project B and want to call from Project A class. uptill is fine. But now how I have to cal l project B method from project A class so how to do this ? I have imlemente d interface in project B and also inherited project A class into project B. so structure of my projets are like this Project A namespace A public class A { --- call project B method } interface IclassB { --- method signature of project B } AND Project B namespace B using A public class b: A , IclassB { --- method which I want to call from Project A } so can you please help me out,how to call class B method from class A. Thanks.

Report this thread to moderator Post Follow-up to this message
Old Post
Naimish
06-20-06 04:34 AM


Sponsored Links




Last Thread Next Thread Next
Search this forum -> 
Post New Thread

C# archive

Show a Printable Version Send to friend Email This Page to Someone! subscribe to this thread Receive updates to this thread
Computer Consultants
Programming Jobs
Visual Basic Controls
SQL Server Programming
Webservices
Java Security
Visual Studio
C# Programming
Visual J++
Software engineering
Open source Software
Perl Programming
PHP Programming
ASP Programming
ASP .NET Programming
Visual Basic Programming
Windows Scripting Host
Java Programming
Java Help
Java Beans
VBScript
Cobol
MAC Applications
Unix Programming
Forum Jump:
All times are GMT. The time now is 11:59 AM.

 
Free MCSE Braindumps | Real Estate Topics

Programming forum archive

Copyrights CodeComments.com 2004 - 2006

Powered by vBulletin Copyright 2000-2006 Jelsoft Enterprises Limited.