-->
These old forums are deprecated now and set to read-only. We are waiting for you on our new forums!
More modern, Discourse-based and with GitHub/Google/Twitter authentication built-in.

All times are UTC - 5 hours [ DST ]



Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 11 posts ] 
Author Message
 Post subject: Circular dependency among layers.
PostPosted: Tue Jul 24, 2007 5:23 pm 
Newbie

Joined: Tue Jul 24, 2007 4:58 pm
Posts: 6
I'm new to NHibernate, but making good progress. The app I'm developing is three tier.

I'm trying to build a modular framework that limits my use of NHibernate to just the 3rd tier. So far I have a Visual Studio solution with one project per tier and two additional projects (interface libraries for the 2nd and 3rd tier). Like so:

SMSClient - Presentation Layer (Tier 1)
SMSCOM - Business Logic Layer (Tier 2)
SMSDA - Data Access Layer (Tier 3)
SMSInterfaces - Interfaces for Tier 2
SMSDAInterfaces - Interfaces for Tier 3

Currently I do not use any form of .NET remoting, however future versions may.

My client therefor has a reference to the SMSCOM project and the SMSInterfaces project. If I switch to remoting I'll remove the reference to SMSCOM and have a factory on the server that creates my objects.

My problem revolves around the SMSDA and SMSCOM projects. Obviously I need the SMSDA layer to be able to make objects (NHibernate needs access to the POCO's). Therefor the SMSDA project should have reference to SMSCOM. However, SMSCOM also needs to be able to call methods inside of the SMSDA library, so it should have a reference to SMSCOM.

Every attempt to add SMSDA to the SMSCOM project produces the error: "A reference to 'SMSCOM' could not be added. Adding this project as a reference would cause a circular dependency."

If this is the case, how exactly is a modular design supposed to be achieved?

More specifically, is there a design pattern or something I'm missing that could help in overcoming this error.


Top
 Profile  
 
 Post subject:
PostPosted: Tue Jul 24, 2007 5:45 pm 
Hibernate Team
Hibernate Team

Joined: Tue Jun 13, 2006 11:29 pm
Posts: 315
Location: Calgary, Alberta, Canada
Hi, your question has more to do with a proper architecture than what NHibernate is designed to help you with; this is not the proper forum for it.

The short answer to your question, however, is SMSCOM and SMSDA should depend on SMSInterfaces and SMSDAInterfaces, but not on each other. You will likely need the help of some Dependency Injection (aka Inversion of Control) library to help you achieve that. Check out Spring.NET.

_________________
Karl Chu


Top
 Profile  
 
 Post subject:
PostPosted: Tue Jul 24, 2007 7:14 pm 
Newbie

Joined: Tue Jul 24, 2007 4:58 pm
Posts: 6
Sorry for the off topic post. That was more to do with architecture rather than NHibernate. However, I can relate the two...

I found a possible solution to my issue by creating a reference to the SMSCOM library via code:

Assembly smsCOM = Assembly.Load("SMSCOM");

IUser user = (IUser) smsCOM.CreateInstance("SMSCOM.UserManagement.User");

Looks like it works great.

Here's the real stumper. How do I get NHibernate to create my objects that way? I need something like the following to return type User (or IUser) with the actual class coming from the assembly.

ISession session = NHibernateHelper.GetCurrentSession();
IQuery q = session.CreateQuery("FROM Users AS User");

Is this even possible?

-Mike.


Top
 Profile  
 
 Post subject: Re: Circular dependency among layers.
PostPosted: Tue Jul 24, 2007 7:24 pm 
Regular
Regular

Joined: Fri Jan 27, 2006 2:32 pm
Posts: 102
Location: California, USA
MBursill wrote:
I'm new to NHibernate, but making good progress. The app I'm developing is three tier.


Cool. You're approach is a little different than my experience, so my response might not work for you...

MBursill wrote:
(NHibernate needs access to the POCO's).


It does???

My data layer only references NHibernate and a "Core" assembly that has some interfaces and other common (but NOT POCO) objects.

Again, maybe I don't understand what you're trying to do, but I'm not seeing why your DA layer needs a reference to the POCO assembly.


Top
 Profile  
 
 Post subject:
PostPosted: Tue Jul 24, 2007 7:31 pm 
Newbie

Joined: Tue Jul 24, 2007 4:58 pm
Posts: 6
Maybe I'm wrong, maybe it doesn't need reference to the POCO's. I'm making that assumption because of the mapping file.

The one line:

<class name="User" table="Users">

I think that is what is giving me troubles. I have that mapping file inside my DA layer, perhaps I need to move it to the BLL and NHibernate will make the reference to the middle tier for me?

I was hoping to keep everything NHibernate specific (including mapping files) inside the DA layer, but I'll give this a shot.


Top
 Profile  
 
 Post subject:
PostPosted: Tue Jul 24, 2007 7:42 pm 
Regular
Regular

Joined: Fri Jan 27, 2006 2:32 pm
Posts: 102
Location: California, USA
MBursill wrote:
<class name="User" table="Users">

I think that is what is giving me troubles. I have that mapping file inside my DA layer, perhaps I need to move it to the BLL and NHibernate will make the reference to the middle tier for me?


You can have your mapping files pretty much anywhere. They just need to be loaded by NHibernate when you configure your SessionFactory.

MBursill wrote:
I was hoping to keep everything NHibernate specific (including mapping files) inside the DA layer, but I'll give this a shot.


Here's what I have. I have a BusinessObject assembly. In that assembly I have my hbm.xml files. (So, my POCOs and the POCO.hbm.xml files are in the same assembly)

There is NO reference between my DA assembly and my BO assembly.

But, my DA layer has this code which loads the BO assembly at runtime:

Code:
_nhConfiguration.AddAssembly("MyBOAssembly");


That is how NHibernate gets to "know" about your POCO's, but it isn't a reference like you would create in Visual Studio.


Top
 Profile  
 
 Post subject:
PostPosted: Tue Jul 24, 2007 8:02 pm 
Newbie

Joined: Tue Jul 24, 2007 4:58 pm
Posts: 6
ohhhhhhhh, I get it! *slaps forehead*

That's so simple. I love it.

I think you kinda solved my problem of "where does the reference go".

Now, you say your DA layer knows nothing about the POCO, so how do you write the query?

Currently I have:

ISession session = NHibernateHelper.GetCurrentSession();
IQuery q = session.CreateQuery("from Users as IUser");

return q.List<IUser>();

and I keep getting the error:

"unexpected token: as [from Users as IUser]"

It's the same error I get if I replace IUser with User inside the query string.

I suppose I want IUser types since my DA layer wont know anything about the User type.


Top
 Profile  
 
 Post subject:
PostPosted: Wed Jul 25, 2007 4:29 am 
Regular
Regular

Joined: Wed Apr 25, 2007 4:18 am
Posts: 51
Location: Belarus, Gomel
Hi

"as IUser" - is a sort of alias for HQL query - it doesn't have any other meaning (I suppose you want to tell NHibernate to cast all the resultant object references to IUser interface).

BTW why do you want to cast results to interface in query itself? You have explicitly implemented interface in User class? Otherwise you'll have no problems accessing IUser members by reference of type User...

P.S. And if you class name is User - you have to use "from User" - not "from Users". HQL must use only class and property names - not table and column names...

_________________
WBR, Igor


Top
 Profile  
 
 Post subject:
PostPosted: Wed Jul 25, 2007 1:23 pm 
Newbie

Joined: Tue Jul 24, 2007 4:58 pm
Posts: 6
That did the trick! :-)

And you're right, it's redundant to specify "as IUser" since User explicitly implements IUser.

One last small question.

Why is it necessary to define all methods of the mapped object as Virtual, and is there a way to "turn this off"?

-Mike.


Top
 Profile  
 
 Post subject:
PostPosted: Thu Jul 26, 2007 4:04 am 
Regular
Regular

Joined: Wed Apr 25, 2007 4:18 am
Posts: 51
Location: Belarus, Gomel
Hi

First of all I assume you realy have implicit interface implementation, not explicit (explicit implementation will force you to cast reference to IUser).

As for virtual modifier - it is needed for proper proxy object creation - proxy must be able to extend your POCO class (via inheritance), and so it have to intercept ALL object access activities (well, really there are some exceptions - id property access for example) - as it will definetely lead to error - trying to use any method or property with uninitialized proxy. Interception in this cases mean "initialize proxy and call base/POCO method implementation".
The only way to "turn this off" - is turning off lazy loading - bad idea in common cases (without lazy loading, you may initiate full DB loading - one object retreiving will force all it's associations retreiving, and they will retreive theirs accociations and so on).

_________________
WBR, Igor


Top
 Profile  
 
 Post subject:
PostPosted: Mon Jul 30, 2007 5:08 pm 
Beginner
Beginner

Joined: Mon Jul 30, 2007 4:58 pm
Posts: 21
you should use dependency injection with Castle windsor or spring.net


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 11 posts ] 

All times are UTC - 5 hours [ DST ]


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
© Copyright 2014, Red Hat Inc. All rights reserved. JBoss and Hibernate are registered trademarks and servicemarks of Red Hat, Inc.