Circular references ?

D

Dave S

Anyone know how to get round the problem of circular references in VB.NET
(sorry I'm a .NET newbie).
I create one project which has 2 classes in it, MyHandler and MyObject.
MyHandler just needs to call another class in a different project and pass a
parameter of type MyObject to it.
So the class in the different project needs to import the first project
namespace so it know what MyObject is.
The MyHandler class needs to import the second project namespace so it can
call the class in the second project.

This doesn't seem to be allowed in .NET even though Java could easily do
this.

See code below :
(1st project : namespace = MyClass.Test1)

Public Class MyHandler
Public Function DoSomething(ByVal obj As MyObject) As String
Dim a As New [MyClass].Test2.MyAction
Return a.DoMethod(obj)[/QUOTE]
End Function
End Class

Public Class MyObject
Private a, b As String
Public Property attrib1() As String
Get
Return a
End Get
Set(ByVal Value As String)
a = Value
End Set
End Property
Public Property attrib2() As String
Get
Return b
End Get
Set(ByVal Value As String)
b = Value
End Set
End Property
End Class


(2nd project : namespace = MyClass.Test2)

Imports [MyClass].Test1

Public Class MyAction
Public Function DoMethod(ByVal obj As MyObject) As String
Return obj.attrib1
End Function
End Class



The line highlighted in red above fails because according to .NET it doesn't
know what type the value called 'obj' is when it comes to passing it to the
method in the 2nd project.
The error I get is :

H:\Work\testbed\MyClass.Test1\MyHandler.vb(4): Reference required to
assembly 'MyClass.Test1' containing the type 'MyClass.Test1.MyObject'. Add
one to your project.




This seems a really basic piece of functionality and I must be declaring
something incorrectly here

Any ideas ??
 
E

Erik Frey

Dave S said:
Anyone know how to get round the problem of circular references in VB.NET
(sorry I'm a .NET newbie).
I create one project which has 2 classes in it, MyHandler and MyObject.
MyHandler just needs to call another class in a different project and pass a
parameter of type MyObject to it.
So the class in the different project needs to import the first project
namespace so it know what MyObject is.
The MyHandler class needs to import the second project namespace so it can
call the class in the second project.

Typically this is adressed by creating a third project that contains your
business types in it.

Then have your other two projects refer to this new project, to have access
to the common type (so in your case, put MyObject in the third project).

Also, keep in mind that even if you have three projects in a solution, you
still have to add the project references manually (right click on
References - > Add References -> Projects tab)

Erik
 
D

Dave S

Erik,

Thanks for this, I just wanted to confirm that it's not possible to do it
with just 2 projects.
I tried moving my object into another project (so it's sort of an interface
project) and then each of the other projects can reference that project
without causing the circular reference problem.
I just thought it was a bit messy when in Java you could easily do this
without a middleman package containing the object you want to pass between
the classes.
At least I know that it wasn't something I'd missed out when declaring the 2
projects initially.
Will have to remember this one in future (I've been struggling with this all
afternoon)

Dave
 
E

Erik Frey

Dave S said:
Erik,

Thanks for this, I just wanted to confirm that it's not possible to do it
with just 2 projects.

If you don't want a third common class, your other option is to move the
MyObject class declaration into the second project that you're trying to
send it to. Then, just reference from your first project (that still
contains MyHandler).

But no - two projects cannot reference eachother.

Erik
 
J

Jason Sobell

You can't directly call from B to A, but you can pass back events with the
package as a parameter, and this is the standard approach to your original
problem.
MyHandler simply raises the event without requiring intimate knowledge
(i.e. dependency) on project B.

This is not a VB.Net specific issue. It applies to all OO languages. Java
uses interfaces or events to avoid the issue, and you can do the same in
VB.

Cheers,
Jason
 
D

Dave S

Jason,

Not sure I understand that one but I can try and look into raising events.
Any code examples of this anywhere ?

Thanks
Dave
 
D

Dave S

Erik,

Yes that's another approach.
Haven't tried that one out but I'm sure it will work because it removes the
need for project 2 being dependent on project 1.

Thanks
Dave
 
J

Jason Sobell

Hi,
It's something along the lines of:

Project 1:
Public Class MyObject
blah
End Class

Public Class MyHandler
Public Event RequestData(dataObj as MyObject

Public Sub Doeventplease()
Dim obj As New MyObject(blah)
RaiseEvent RequestData(obj)
'obj may have been modified by the event handler...
End Sub
End Class


In you main Project2 app you can reference Project1.
Then, you can call your Project1 function, and if it needs to obtain more
info from Project1 it can do so via the event.

E.g.
Project2:

Private WithEvents P1object As New Project1.MyHandler

Public Sub Main()
P1object.DoSomething
'If the P1object requires some data from you, it may now generate an event
'that will be caught by the event handler below:

End Sub

Private Sub RequestDataHandler(ByValue myob As Project1.MyObject) _
Handles P1object.RequestData
'Do something with myob, or alter values in it etc.
End Sub


A typical place I use this is if I'm writing a custom control.
The control may require data from the form on which it's placed, and I
can't have a direct link from the control to a custom method on my form, so
I have events such as "RequestLanguageEditor" or "RequestValidation" that
pass enough information to allow the underlying form to perform a
calculation, and I might have a 'ByRef Cancel As Boolean' to allow me to
easily return a status to the control itself.

I'm afraid this is mainly a mindset problem rather than technical, but
hopefully this gives an idea. If you give a more concrete problem
description then a few people may give alternative architectures.

Cheers,
Jason

p.s. The VB.Net code above is typed from memory, so the syntax may be dodgy
:)
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top