0

In a typical organization application i create, entities User,Projects,Company,Contacts exists. For the user class defined below i think i will hit with a circular dependency. How should i modify the class below to solve the problem.

User

  • Username

  • Company

  • Projects List<Projects>

Project

  • ProjectName

  • Resources List<Resource>

  • Project Head User

Resource

  • ResourceId

  • ProjectId

  • ReportingHead User

You must have already found the flaw but,as you see ReportingHead, ProjectLead is already User class this makes it query for information about projects for them ,which will result in another cycle to retrieve the users for their project.

Even though resource is associated with project i will have to add a property projectId( First it was of type project) because i had a IResourceRepository to create resource for a project which would return a instance of Resource. How should the class be designed now so that it makes sense?

Community
  • 1
  • 1
Deeptechtons
  • 10,945
  • 27
  • 96
  • 178
  • 3
    Where is the problem? I don't see any! You can have two way dependencies like that. – Daniel Hilgarth Jan 24 '12 at 10:02
  • @DanielHilgarth run through this case. I Query for user **daniel** i will get list of his projects, each project will have projectlead, resource (which in turn has reporting head). ProjectHead, ReportingHead are User class so, to fill their details i will have to query for Projects which in turn will land in point 1. – Deeptechtons Jan 24 '12 at 10:06
  • As I said, that is not a problem... Just try it. However, I wonder whether or not you are asking this question in the context of an ORM like NHibernate, because you are talking about "querying" stuff. – Daniel Hilgarth Jan 24 '12 at 10:08
  • @DanielHilgarth No Orm's used. I want to decouple the Project and User class here. – Deeptechtons Jan 24 '12 at 10:10
  • There is no reason to do that, because there is no problem with the way you have it right now... – Daniel Hilgarth Jan 24 '12 at 10:13
  • 1
    I agree with Daniel that this might work. But imo you should try to don´t have bidirectional relations as long as it´s reasonable possible. It gives you cleaner code in many ways. – Glenn Jan 24 '12 at 10:27
  • 1
    @Daniel Hilgarth: If the OP is recursively populating the entire data structure he could end up in an infinite loop (and a stack overflow). A caching layer should prevent that? – Phil Gan Jan 24 '12 at 10:31
  • @PhilGan you understood what i was exactly trying to explain Daniel, but he was too narrow minded. Bidirectional as he pointed would not help me much in this scenario :( – Deeptechtons Jan 24 '12 at 10:45
  • @Deeptechtons: Your data structure seems appropriate but you need to make sure you only ever load each entity once and reference the same instance of that entity everywhere it occurs. And avoid infinite loops in any tree-walking operations you might need. – Phil Gan Jan 24 '12 at 14:31

1 Answers1

1

You could spend some time reading on aggregates and aggregate roots.

What's an Aggregate Root?

Decide one of your entities as a root and make a try and see if it fits your scenarios. I give you an example. This is very hard without knowing your scenarios though so see it as a example:

I go for Companyas aggregate root.

Company
  Name:string
  Projects:IList<Project>

Project
  ProjectName:string
  Resources:IList<Resource>
  Projecthead:Employee

Resource
  Employee:Employee
  (ResourceType probably)

Employee
  Name

(Ids are left out but will probably be in some baseclass if you want to DB Persist)

Now you must make sure that you only access this Aggregate-root through the root Company. This is about isolation and it feels pretty weird that you cannot do a method like user.GetAllMyProjects() anymore but that will make it easier for you later on. Instead you can make a method like project.HasGivenUserAccess(User user). Thats probably enough but it depends on your scenarios.

Feel free to attack this design with some scenario that you don´t think it handles and I will edit my post.

Community
  • 1
  • 1
Glenn
  • 1,955
  • 2
  • 15
  • 23
  • How about Company as aggregate. Projects, Resource, Client come under it. Now the hierarchy will look like User under him company which will now contain projects and it goes. Since i get a `List<>` i would use a predicate match to find appropriate users, projects, resource – Deeptechtons Jan 24 '12 at 10:54
  • Absolutely, it all depends on your scenarios. I saw company as some simple object only to describe where a User was working (consultant). But if the application centers around companies and handles their projects Company makes perfectly sense. Perhaps the User actually is employee? – Glenn Jan 24 '12 at 10:59
  • yup User is the employee. I will right away workout the a proof of sample and report back here. Will mark as answer soon :) thanks – Deeptechtons Jan 24 '12 at 11:02