Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. General Programming
  3. Design and Architecture
  4. Composed Business Objects

Composed Business Objects

Scheduled Pinned Locked Moved Design and Architecture
csharpdesignhelpquestionasp-net
23 Posts 4 Posters 24 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • P Offline
    P Offline
    Pawel Krakowiak
    wrote on last edited by
    #1

    Hi! I wasn't sure whether to post this in ASP.NET or Design and Architecture forum, but decided to land it here after all as I believe the same would apply to a WinForms app or even a web service. I am working on an ASP.NET 2.0 project, this is my first attempt at a real multi tier architecture, before I was just binding a DataSet to my WebForms directly. I have a DAL, a BLL and an UI. All is fine, they work well together, but I came to the point where I need to display some reports in a GridView and my grasp of business layer started to fall apart. ;) Look, the project is about embeddable web widgets, every widget belongs to some user. I have (among others) some classes in BLL (they communicate with DAL for CRUD and other database operations, BLL does not know anything about the database): 1. WidgetsBLL - this class 'manages' Widgets. You can create new widgets here, retrieve all widgets, retrieve widgets belonging to a particular user, etc. 2. Widget - this class represents a particular widget. It knows the widget's URL, clickthru count, theme and so on. 3. UsersBLL - same as WidgetsBLL, just deals with Users. 4. User - represents a user, stores data such as first & last name, e-mail address, etc. It all worked great so far, but now I came to the point where I must display combined data in a GridView. I need data from Widget class (such as widget's ID, name and clickthru count) as well as owner's data from User class (first & last name, e-mail). Now, this data cannot be retrieved from a single class as you can see. I need to get a Widget instance, then get a User instance and display a list of rows which are built from those two classes, so the GridView needs columns such as: Widget.WidgetId | Widget.WidgetName | User.LastName | User.Email I am not sure what one should do to solve such problem, I don't have experience with this kind of architecture. I might just create a new class (WidgetStats?) - this seems like the easiest approach, but somehow it looks like bad design to me, because widget statistics is not a real object - it looks kind of artificial, doesn't it? What is the best way to return an object composed of other objects? I began by calling WidgetsBLL.GetWidgets() and binding the result to the GridView. Then I can have TemplateFields and retrieve for example user's e-mail. But what about sorting in this scenario?! Please, help. I have been trying to work this out for two days. :sigh:

    Kind regards, Pawel Krakowiak

    L M 2 Replies Last reply
    0
    • P Pawel Krakowiak

      Hi! I wasn't sure whether to post this in ASP.NET or Design and Architecture forum, but decided to land it here after all as I believe the same would apply to a WinForms app or even a web service. I am working on an ASP.NET 2.0 project, this is my first attempt at a real multi tier architecture, before I was just binding a DataSet to my WebForms directly. I have a DAL, a BLL and an UI. All is fine, they work well together, but I came to the point where I need to display some reports in a GridView and my grasp of business layer started to fall apart. ;) Look, the project is about embeddable web widgets, every widget belongs to some user. I have (among others) some classes in BLL (they communicate with DAL for CRUD and other database operations, BLL does not know anything about the database): 1. WidgetsBLL - this class 'manages' Widgets. You can create new widgets here, retrieve all widgets, retrieve widgets belonging to a particular user, etc. 2. Widget - this class represents a particular widget. It knows the widget's URL, clickthru count, theme and so on. 3. UsersBLL - same as WidgetsBLL, just deals with Users. 4. User - represents a user, stores data such as first & last name, e-mail address, etc. It all worked great so far, but now I came to the point where I must display combined data in a GridView. I need data from Widget class (such as widget's ID, name and clickthru count) as well as owner's data from User class (first & last name, e-mail). Now, this data cannot be retrieved from a single class as you can see. I need to get a Widget instance, then get a User instance and display a list of rows which are built from those two classes, so the GridView needs columns such as: Widget.WidgetId | Widget.WidgetName | User.LastName | User.Email I am not sure what one should do to solve such problem, I don't have experience with this kind of architecture. I might just create a new class (WidgetStats?) - this seems like the easiest approach, but somehow it looks like bad design to me, because widget statistics is not a real object - it looks kind of artificial, doesn't it? What is the best way to return an object composed of other objects? I began by calling WidgetsBLL.GetWidgets() and binding the result to the GridView. Then I can have TemplateFields and retrieve for example user's e-mail. But what about sorting in this scenario?! Please, help. I have been trying to work this out for two days. :sigh:

      Kind regards, Pawel Krakowiak

      L Offline
      L Offline
      led mike
      wrote on last edited by
      #2

      Pawel Krakowiak wrote:

      but now I came to the point where I must display combined data in a GridView. I need data from Widget class

      If I understand your post correctly a "widget" is a presentation object or "view" object, therefore other views are never going to "get data" from it. The GridView is another presentation object so it would get all it's data through the back end services ( business, session, database ).

      Pawel Krakowiak wrote:

      this is my first attempt at a real multi tier architecture

      Pawel Krakowiak wrote:

      I don't have experience with this kind of architecture.

      That's not architecture it's software design. You are designing your business logic and views that all execute in the middle tier. You are not creating tiers you are designing.

      P 1 Reply Last reply
      0
      • L led mike

        Pawel Krakowiak wrote:

        but now I came to the point where I must display combined data in a GridView. I need data from Widget class

        If I understand your post correctly a "widget" is a presentation object or "view" object, therefore other views are never going to "get data" from it. The GridView is another presentation object so it would get all it's data through the back end services ( business, session, database ).

        Pawel Krakowiak wrote:

        this is my first attempt at a real multi tier architecture

        Pawel Krakowiak wrote:

        I don't have experience with this kind of architecture.

        That's not architecture it's software design. You are designing your business logic and views that all execute in the middle tier. You are not creating tiers you are designing.

        P Offline
        P Offline
        Pawel Krakowiak
        wrote on last edited by
        #3

        led mike wrote:

        If I understand your post correctly a "widget" is a presentation object or "view" object

        Not exactly, it is a domain object which represents data from the database and allows the user to modify that data - such as giving it a name, assigning a URL to it, choosing a theme, etc. The user control which renders this is another subject. :) I need to display GridView rows composed of some fields from Widget class and some fields from User (widget's owner) class. I am wondering whether I shouldn't just create a WidgetStatistics class which would have 1 property of type Widget and 1 property of type User and just bind my grid to that. I don't know if it's a good idea, definitely easier.

        Kind regards, Pawel Krakowiak

        L 1 Reply Last reply
        0
        • P Pawel Krakowiak

          led mike wrote:

          If I understand your post correctly a "widget" is a presentation object or "view" object

          Not exactly, it is a domain object which represents data from the database and allows the user to modify that data - such as giving it a name, assigning a URL to it, choosing a theme, etc. The user control which renders this is another subject. :) I need to display GridView rows composed of some fields from Widget class and some fields from User (widget's owner) class. I am wondering whether I shouldn't just create a WidgetStatistics class which would have 1 property of type Widget and 1 property of type User and just bind my grid to that. I don't know if it's a good idea, definitely easier.

          Kind regards, Pawel Krakowiak

          L Offline
          L Offline
          led mike
          wrote on last edited by
          #4

          Pawel Krakowiak wrote:

          and allows the user to modify that data

          If the user interacts with it, it is a presentation object. I am far to confused by your posts to help.

          P 1 Reply Last reply
          0
          • L led mike

            Pawel Krakowiak wrote:

            and allows the user to modify that data

            If the user interacts with it, it is a presentation object. I am far to confused by your posts to help.

            P Offline
            P Offline
            Pawel Krakowiak
            wrote on last edited by
            #5

            led mike wrote:

            If the user interacts with it, it is a presentation object.

            Class user, not application user. I guess I can't express my problem better. :( How it works in code is like this: WidgetsBLL widgetsLogic = new WidgetsBLL(); Widget widget = widgetsLogic.GetWidgetById(13); Now you can access various fields of the widget: widget.WidgetId widget.FriendlyName And so on. You also have a User class, which has properties such as FirstName, LastName, etc. I need to present combined data, so in one row we have WidgetId but also user's FirstName - as you can see this data belongs to two different classes. I am not sure whether to design a third class and include both Widget and User by composition or to do something else. That is my problem I tried to describe.

            Kind regards, Pawel Krakowiak

            L 1 Reply Last reply
            0
            • P Pawel Krakowiak

              led mike wrote:

              If the user interacts with it, it is a presentation object.

              Class user, not application user. I guess I can't express my problem better. :( How it works in code is like this: WidgetsBLL widgetsLogic = new WidgetsBLL(); Widget widget = widgetsLogic.GetWidgetById(13); Now you can access various fields of the widget: widget.WidgetId widget.FriendlyName And so on. You also have a User class, which has properties such as FirstName, LastName, etc. I need to present combined data, so in one row we have WidgetId but also user's FirstName - as you can see this data belongs to two different classes. I am not sure whether to design a third class and include both Widget and User by composition or to do something else. That is my problem I tried to describe.

              Kind regards, Pawel Krakowiak

              L Offline
              L Offline
              led mike
              wrote on last edited by
              #6

              Pawel Krakowiak wrote:

              include both Widget and User by composition or to do something else

              Composition is reasonable. You are asking an Object Oriented Analysis and Design question. Without seeing your analysis and existing design it's difficult to offer any meaningful advice but under the heading of General points: Are you using interfaces? and...

              Pawel Krakowiak wrote:

              Now you can access various fields of the widget: widget.WidgetId widget.FriendlyName

              See this article[^]

              1 Reply Last reply
              0
              • P Pawel Krakowiak

                Hi! I wasn't sure whether to post this in ASP.NET or Design and Architecture forum, but decided to land it here after all as I believe the same would apply to a WinForms app or even a web service. I am working on an ASP.NET 2.0 project, this is my first attempt at a real multi tier architecture, before I was just binding a DataSet to my WebForms directly. I have a DAL, a BLL and an UI. All is fine, they work well together, but I came to the point where I need to display some reports in a GridView and my grasp of business layer started to fall apart. ;) Look, the project is about embeddable web widgets, every widget belongs to some user. I have (among others) some classes in BLL (they communicate with DAL for CRUD and other database operations, BLL does not know anything about the database): 1. WidgetsBLL - this class 'manages' Widgets. You can create new widgets here, retrieve all widgets, retrieve widgets belonging to a particular user, etc. 2. Widget - this class represents a particular widget. It knows the widget's URL, clickthru count, theme and so on. 3. UsersBLL - same as WidgetsBLL, just deals with Users. 4. User - represents a user, stores data such as first & last name, e-mail address, etc. It all worked great so far, but now I came to the point where I must display combined data in a GridView. I need data from Widget class (such as widget's ID, name and clickthru count) as well as owner's data from User class (first & last name, e-mail). Now, this data cannot be retrieved from a single class as you can see. I need to get a Widget instance, then get a User instance and display a list of rows which are built from those two classes, so the GridView needs columns such as: Widget.WidgetId | Widget.WidgetName | User.LastName | User.Email I am not sure what one should do to solve such problem, I don't have experience with this kind of architecture. I might just create a new class (WidgetStats?) - this seems like the easiest approach, but somehow it looks like bad design to me, because widget statistics is not a real object - it looks kind of artificial, doesn't it? What is the best way to return an object composed of other objects? I began by calling WidgetsBLL.GetWidgets() and binding the result to the GridView. Then I can have TemplateFields and retrieve for example user's e-mail. But what about sorting in this scenario?! Please, help. I have been trying to work this out for two days. :sigh:

                Kind regards, Pawel Krakowiak

                M Offline
                M Offline
                Mark Churchill
                wrote on last edited by
                #7

                It seems to me you should be binding your datagrid to Widget.WidgetId | Widget.WidgetName | Widget.Owner.LastName | Widget.Owner.Email This is a fairly important distinction - the example you gave doesnt appear to take advantage of the relationship between Widgets and Users. You might not want your BLL to know about the exact FK relationship in the database, but the fact that Widgets have an Owner is part of your domain, and there is no escaping that. How you implement these properties on the Widget class is up to you. You might also want to consider using a tool that handles the database mapping for you. My company (linked in my signature) provides such a product, which is free for non-commercial use.

                Mark Churchill Director Dunn & Churchill

                P 1 Reply Last reply
                0
                • M Mark Churchill

                  It seems to me you should be binding your datagrid to Widget.WidgetId | Widget.WidgetName | Widget.Owner.LastName | Widget.Owner.Email This is a fairly important distinction - the example you gave doesnt appear to take advantage of the relationship between Widgets and Users. You might not want your BLL to know about the exact FK relationship in the database, but the fact that Widgets have an Owner is part of your domain, and there is no escaping that. How you implement these properties on the Widget class is up to you. You might also want to consider using a tool that handles the database mapping for you. My company (linked in my signature) provides such a product, which is free for non-commercial use.

                  Mark Churchill Director Dunn & Churchill

                  P Offline
                  P Offline
                  Pawel Krakowiak
                  wrote on last edited by
                  #8

                  Mark Churchill wrote:

                  It seems to me you should be binding your datagrid to Widget.WidgetId | Widget.WidgetName | Widget.Owner.LastName | Widget.Owner.Email

                  Yeah, I redesigned the application, so now my business objects make more sense. I could write a SQL query (stored proc) which would return data from joined tables, then create another Table Adapter and BO. But this doesn't look good to me in terms of design. First rule is you should not update the business layer to meet the UI requirements, it should be exactly the opposite. And that's why I don't like the idea of creating a new BO just for displaying statistics in a GridView in the presentation layer. My problem (at least a similar one) was already discussed at ASP.NET Forums[^]. Thanks.

                  Kind regards, Pawel Krakowiak

                  L M 2 Replies Last reply
                  0
                  • P Pawel Krakowiak

                    Mark Churchill wrote:

                    It seems to me you should be binding your datagrid to Widget.WidgetId | Widget.WidgetName | Widget.Owner.LastName | Widget.Owner.Email

                    Yeah, I redesigned the application, so now my business objects make more sense. I could write a SQL query (stored proc) which would return data from joined tables, then create another Table Adapter and BO. But this doesn't look good to me in terms of design. First rule is you should not update the business layer to meet the UI requirements, it should be exactly the opposite. And that's why I don't like the idea of creating a new BO just for displaying statistics in a GridView in the presentation layer. My problem (at least a similar one) was already discussed at ASP.NET Forums[^]. Thanks.

                    Kind regards, Pawel Krakowiak

                    L Offline
                    L Offline
                    led mike
                    wrote on last edited by
                    #9

                    Pawel Krakowiak wrote:

                    First rule is you should not update the business layer to meet the UI requirements

                    I never heard that rule, can you provide a link to your source?

                    P 1 Reply Last reply
                    0
                    • L led mike

                      Pawel Krakowiak wrote:

                      First rule is you should not update the business layer to meet the UI requirements

                      I never heard that rule, can you provide a link to your source?

                      P Offline
                      P Offline
                      Pawel Krakowiak
                      wrote on last edited by
                      #10

                      led mike wrote:

                      I never heard that rule, can you provide a link to your source?

                      It's called common sense. ;) The whole idea behind decoupled modules is to make them pluggable, so you can throw out your ASP.NET UI and plug in WinForms and it will still work, because the business layer stays the same. If you start adding UI related stuff to your BOs you are coupling those two layers again. In the end when you want to switch the UI you have to rewrite the BOs or end up with BOs hanging in the air (not used anymore) and writing new ones. I guess the size of your project is important and its particular requirements, right? Follow the ASP.NET Forums discussion if you want, I am just agreeing with some opinions there.

                      Kind regards, Pawel Krakowiak

                      L 1 Reply Last reply
                      0
                      • P Pawel Krakowiak

                        led mike wrote:

                        I never heard that rule, can you provide a link to your source?

                        It's called common sense. ;) The whole idea behind decoupled modules is to make them pluggable, so you can throw out your ASP.NET UI and plug in WinForms and it will still work, because the business layer stays the same. If you start adding UI related stuff to your BOs you are coupling those two layers again. In the end when you want to switch the UI you have to rewrite the BOs or end up with BOs hanging in the air (not used anymore) and writing new ones. I guess the size of your project is important and its particular requirements, right? Follow the ASP.NET Forums discussion if you want, I am just agreeing with some opinions there.

                        Kind regards, Pawel Krakowiak

                        L Offline
                        L Offline
                        led mike
                        wrote on last edited by
                        #11

                        Pawel Krakowiak wrote:

                        It's called common sense.

                        I see you are joking but seriously I have my own Number One Rule: Don't make stuff up. What I mean by that is that so much information is available now there is no need to in 99.9% of the work I do.

                        Pawel Krakowiak wrote:

                        and its particular requirements, right?

                        Yes requirements, and analysis, are the key in your problem. What I mean is, if you have discovered a missing requirement or incomplete analysis then of course it might require a change in any layer(s) or part(s) of your system or even design dependencies forcing a refactoring to alter the design.

                        Pawel Krakowiak wrote:

                        but now I came to the point where I must display combined data in a GridView

                        Certainly that could have been anticipated but that is what iterative development is about. Understanding that we are not always able to have all the requirements before we start designing or that our analysis might be flawed or have holes. When these issues occur what we hope to find is that our design supports adding the new feature but even that is not always possible.

                        P 1 Reply Last reply
                        0
                        • L led mike

                          Pawel Krakowiak wrote:

                          It's called common sense.

                          I see you are joking but seriously I have my own Number One Rule: Don't make stuff up. What I mean by that is that so much information is available now there is no need to in 99.9% of the work I do.

                          Pawel Krakowiak wrote:

                          and its particular requirements, right?

                          Yes requirements, and analysis, are the key in your problem. What I mean is, if you have discovered a missing requirement or incomplete analysis then of course it might require a change in any layer(s) or part(s) of your system or even design dependencies forcing a refactoring to alter the design.

                          Pawel Krakowiak wrote:

                          but now I came to the point where I must display combined data in a GridView

                          Certainly that could have been anticipated but that is what iterative development is about. Understanding that we are not always able to have all the requirements before we start designing or that our analysis might be flawed or have holes. When these issues occur what we hope to find is that our design supports adding the new feature but even that is not always possible.

                          P Offline
                          P Offline
                          Pawel Krakowiak
                          wrote on last edited by
                          #12

                          led mike wrote:

                          I see you are joking but seriously I have my own Number One Rule: Don't make stuff up.

                          I shouldn't have said 'rule', rather 'suggestion' or 'good practice'. Of course there are no rules which say you can't include UI stuff in your business layer.

                          led mike wrote:

                          Certainly that could have been anticipated but that is what iterative development is about.

                          In this particular project the statistics were to be supported by an external system, but we had to put the website in an IFrame (which wasn't planned) and the external system doesn't work that way, so I had to write my own statistics "engine" and now I need to include a couple of stats pages. But this doesn't mean I should be adding Business Objects which represent "a statistic", which really consists of a few fields taken from two objects which already exists - GUI should do the job - it already can get the objects and should take care of combining and displaying them. I was looking for somebody to tell me maybe that creating a new BO just for this purpose was OK, even though I didn't like it, hence my original question. :) Anyway, as you originally said, this would be difficult without showing my classes. I asked a theoretical question. Oh, by the way - regarding the 'accessors are evil' article - you must have public properties in order to bind ASP.NET controls to data. .NET Framework itself is full of properties, sometimes they are more readable in code and easier to use, but as someone (maybe it was in that article?) said - working for Sun or Microsoft doesn't magically improve your skills. ;)

                          Kind regards, Pawel Krakowiak

                          1 Reply Last reply
                          0
                          • P Pawel Krakowiak

                            Mark Churchill wrote:

                            It seems to me you should be binding your datagrid to Widget.WidgetId | Widget.WidgetName | Widget.Owner.LastName | Widget.Owner.Email

                            Yeah, I redesigned the application, so now my business objects make more sense. I could write a SQL query (stored proc) which would return data from joined tables, then create another Table Adapter and BO. But this doesn't look good to me in terms of design. First rule is you should not update the business layer to meet the UI requirements, it should be exactly the opposite. And that's why I don't like the idea of creating a new BO just for displaying statistics in a GridView in the presentation layer. My problem (at least a similar one) was already discussed at ASP.NET Forums[^]. Thanks.

                            Kind regards, Pawel Krakowiak

                            M Offline
                            M Offline
                            Mark Churchill
                            wrote on last edited by
                            #13

                            I don't totally agree here. Implementation aside, if you were to draw me an ERD then you would agree that Widgets have an Owner of type Person. A person owns none or more widgets. Regardless of whether you have a ASP.Net/Webforms or command line, this relationship exists. You business layer should also have Widget.Owner, and likely Person.Widgets[]. Sure, your database reflects this as a foreign key. Thats fine. Call it a coincidence. Your BL is based off the ERD, your database is also based off the ERD. They do both represent the same things, expect them to be similar.

                            Mark Churchill Director Dunn & Churchill

                            P 1 Reply Last reply
                            0
                            • M Mark Churchill

                              I don't totally agree here. Implementation aside, if you were to draw me an ERD then you would agree that Widgets have an Owner of type Person. A person owns none or more widgets. Regardless of whether you have a ASP.Net/Webforms or command line, this relationship exists. You business layer should also have Widget.Owner, and likely Person.Widgets[]. Sure, your database reflects this as a foreign key. Thats fine. Call it a coincidence. Your BL is based off the ERD, your database is also based off the ERD. They do both represent the same things, expect them to be similar.

                              Mark Churchill Director Dunn & Churchill

                              P Offline
                              P Offline
                              Pawel Krakowiak
                              wrote on last edited by
                              #14

                              Mark Churchill wrote:

                              You business layer should also have Widget.Owner, and likely Person.Widgets[]. Sure, your database reflects this as a foreign key. Thats fine. Call it a coincidence. Your BL is based off the ERD, your database is also based off the ERD.

                              Mark, but this leads to a circular dependency, i.e. a Person has Widgets collection, each widget has an Owner, which is a Person, which has a Widgets collection, each widget has an Owner, which is a Person, which has a Widgets collection, each widget has an Owner... You know what I mean? :) Currently my idea is to have a User class, which contains WidgetList (inherits from List[Widget]), but Widget only has UserId as its owner, not the whole object. If you need the owner, you can retrieve it from UserManager (another class which manages objects of type User). This, of course, means that ASP.NET databinding is not so easy, because I need to add some TemplateFields and fill them in in GridView event handlers.

                              Kind regards, Pawel Krakowiak

                              M 1 Reply Last reply
                              0
                              • P Pawel Krakowiak

                                Mark Churchill wrote:

                                You business layer should also have Widget.Owner, and likely Person.Widgets[]. Sure, your database reflects this as a foreign key. Thats fine. Call it a coincidence. Your BL is based off the ERD, your database is also based off the ERD.

                                Mark, but this leads to a circular dependency, i.e. a Person has Widgets collection, each widget has an Owner, which is a Person, which has a Widgets collection, each widget has an Owner, which is a Person, which has a Widgets collection, each widget has an Owner... You know what I mean? :) Currently my idea is to have a User class, which contains WidgetList (inherits from List[Widget]), but Widget only has UserId as its owner, not the whole object. If you need the owner, you can retrieve it from UserManager (another class which manages objects of type User). This, of course, means that ASP.NET databinding is not so easy, because I need to add some TemplateFields and fill them in in GridView event handlers.

                                Kind regards, Pawel Krakowiak

                                M Offline
                                M Offline
                                Mark Churchill
                                wrote on last edited by
                                #15

                                That circular dependancy seems to be correct behaviour to me. What is important is that the User and the Widget are the same instance every time around. I would expect "somePerson == somePerson.Widgets[0].Owner". This is similar to say a heirachy of Controls on a page. "someThing.Controls[0].Parent" could have you going in circles in a similar manner. Diamond Binding will give you a Owner property on the Widget class of type Person, and an IList on the Person class. The actual implementation of IList depends on whether you have picked lazy-loading. You could also configure an IDictionary where x is a property of Widget that is unique per Person. Think of it this way: Is it incorrect of me to ask "Who is your father's son's father's son's father?". It might be inefficient of me to ask that, but the query has an answer in your problem domain.

                                Mark Churchill Director Dunn & Churchill

                                P 1 Reply Last reply
                                0
                                • M Mark Churchill

                                  That circular dependancy seems to be correct behaviour to me. What is important is that the User and the Widget are the same instance every time around. I would expect "somePerson == somePerson.Widgets[0].Owner". This is similar to say a heirachy of Controls on a page. "someThing.Controls[0].Parent" could have you going in circles in a similar manner. Diamond Binding will give you a Owner property on the Widget class of type Person, and an IList on the Person class. The actual implementation of IList depends on whether you have picked lazy-loading. You could also configure an IDictionary where x is a property of Widget that is unique per Person. Think of it this way: Is it incorrect of me to ask "Who is your father's son's father's son's father?". It might be inefficient of me to ask that, but the query has an answer in your problem domain.

                                  Mark Churchill Director Dunn & Churchill

                                  P Offline
                                  P Offline
                                  Pawel Krakowiak
                                  wrote on last edited by
                                  #16

                                  So, you suggest to have an accessor like this:

                                  private int _ownerId; // This is initialized elsewhere.
                                  
                                  public User Owner
                                  {
                                     get
                                     {
                                        // Lazy loads the User object upon request by using the UserManager class'
                                        // static method.
                                        return UserManager.GetUserById(_ownerId);
                                     }
                                     set
                                     {
                                        // Cast value to User object and retrieve it's ID.
                                        _ownerId = ((User)value).UserId;
                                     }
                                  }
                                  

                                  User = Person, I currently have that class named User, although it conflicts with a class from .NET Framework sometimes, so renaming it to Person is a good idea. This is a simplified example, but something like the above? This would allow to bind easily the property in ASP.NET, like "User.Owner.FullName", but still wouldn't endlessly load objects, right? BTW. Is DiamondBinding an ORM? I have currently a license for EntitySpaces[^], but am not using it at the moment. The way how ORMs present the objects looks like more fitting for the DAL rather than BLL... But this is an another discussion. ;)

                                  Kind regards, Pawel Krakowiak

                                  M 1 Reply Last reply
                                  0
                                  • P Pawel Krakowiak

                                    So, you suggest to have an accessor like this:

                                    private int _ownerId; // This is initialized elsewhere.
                                    
                                    public User Owner
                                    {
                                       get
                                       {
                                          // Lazy loads the User object upon request by using the UserManager class'
                                          // static method.
                                          return UserManager.GetUserById(_ownerId);
                                       }
                                       set
                                       {
                                          // Cast value to User object and retrieve it's ID.
                                          _ownerId = ((User)value).UserId;
                                       }
                                    }
                                    

                                    User = Person, I currently have that class named User, although it conflicts with a class from .NET Framework sometimes, so renaming it to Person is a good idea. This is a simplified example, but something like the above? This would allow to bind easily the property in ASP.NET, like "User.Owner.FullName", but still wouldn't endlessly load objects, right? BTW. Is DiamondBinding an ORM? I have currently a license for EntitySpaces[^], but am not using it at the moment. The way how ORMs present the objects looks like more fitting for the DAL rather than BLL... But this is an another discussion. ;)

                                    Kind regards, Pawel Krakowiak

                                    M Offline
                                    M Offline
                                    Mark Churchill
                                    wrote on last edited by
                                    #17

                                    Yep that seems ok. If the UserManager has a caching strategy of some sort then you won't have any problems with circular references giving you duplicate objects either. (Although theres a redundant cast in that setter ;)). You could also keep a local cache of the child object - this would be more efficient when pulling out say User.Owner.FirstName + User.Owner.LastName - it would avoid two trips to the UserManager. Of course with any caching you have stale-cache issues to solve ;) As for lists, you can have your Widget collection implement IList, but not actually retrieving the objects until iterated or an item requested (lazy loading again). Diamond Binding is an ORM and definition generator. It follows the ActiveRecord model, so its less data-model oriented than other ORMs - so you are mainly dealing with objects at a business level: Customer c = Customer.Find(primaryKey); IList/Customer/ l = Customer.FindAll(); (Edit: Forum broke my generics!) Theres an example on the product page here[^]. Give the Personal Edition a try if you like, theres no functional difference between it and the Professional / Enterprise Editions. We aim to handle the entire data access requirements and just let you build business logic on top of the model we give you.

                                    Mark Churchill Director Dunn & Churchill

                                    P 1 Reply Last reply
                                    0
                                    • M Mark Churchill

                                      Yep that seems ok. If the UserManager has a caching strategy of some sort then you won't have any problems with circular references giving you duplicate objects either. (Although theres a redundant cast in that setter ;)). You could also keep a local cache of the child object - this would be more efficient when pulling out say User.Owner.FirstName + User.Owner.LastName - it would avoid two trips to the UserManager. Of course with any caching you have stale-cache issues to solve ;) As for lists, you can have your Widget collection implement IList, but not actually retrieving the objects until iterated or an item requested (lazy loading again). Diamond Binding is an ORM and definition generator. It follows the ActiveRecord model, so its less data-model oriented than other ORMs - so you are mainly dealing with objects at a business level: Customer c = Customer.Find(primaryKey); IList/Customer/ l = Customer.FindAll(); (Edit: Forum broke my generics!) Theres an example on the product page here[^]. Give the Personal Edition a try if you like, theres no functional difference between it and the Professional / Enterprise Editions. We aim to handle the entire data access requirements and just let you build business logic on top of the model we give you.

                                      Mark Churchill Director Dunn & Churchill

                                      P Offline
                                      P Offline
                                      Pawel Krakowiak
                                      wrote on last edited by
                                      #18

                                      Mark Churchill wrote:

                                      If the UserManager has a caching strategy of some sort then you won't have any problems with circular references giving you duplicate objects either.

                                      I am not sure how to do this yet, can you point me to some articles?

                                      Mark Churchill wrote:

                                      Although theres a redundant cast in that setter

                                      Yes. I thought value was of type object, forum doesn't give me any guidelines. ;P Thanks for all your comments so far.

                                      Kind regards, Pawel Krakowiak

                                      M 1 Reply Last reply
                                      0
                                      • P Pawel Krakowiak

                                        Mark Churchill wrote:

                                        If the UserManager has a caching strategy of some sort then you won't have any problems with circular references giving you duplicate objects either.

                                        I am not sure how to do this yet, can you point me to some articles?

                                        Mark Churchill wrote:

                                        Although theres a redundant cast in that setter

                                        Yes. I thought value was of type object, forum doesn't give me any guidelines. ;P Thanks for all your comments so far.

                                        Kind regards, Pawel Krakowiak

                                        M Offline
                                        M Offline
                                        Mark Churchill
                                        wrote on last edited by
                                        #19

                                        A really simplistic implementation would be to add the caching to your UserManager.Load(object pk). Check the cache, and if its in the cache then return it. Otherwise load the object's data and add it to the cache. You can use a Dictionary for your cache for prototyping. ASP.Net provides a cache (I think you can safely use this outside of the web framework too) that you can add objects to with a key and an expiry. You might want to add some way of forcing a reload of an object as well. To be honest though if you are writing your own data layer you are going to have to draw the line for features somewhere. I haven't done a KLOC count on Diamond Binding for a while - but I'm guessing its approaching the millions, and thats not including NHibernate ;)

                                        Mark Churchill Director Dunn & Churchill

                                        M P 2 Replies Last reply
                                        0
                                        • M Mark Churchill

                                          A really simplistic implementation would be to add the caching to your UserManager.Load(object pk). Check the cache, and if its in the cache then return it. Otherwise load the object's data and add it to the cache. You can use a Dictionary for your cache for prototyping. ASP.Net provides a cache (I think you can safely use this outside of the web framework too) that you can add objects to with a key and an expiry. You might want to add some way of forcing a reload of an object as well. To be honest though if you are writing your own data layer you are going to have to draw the line for features somewhere. I haven't done a KLOC count on Diamond Binding for a while - but I'm guessing its approaching the millions, and thats not including NHibernate ;)

                                          Mark Churchill Director Dunn & Churchill

                                          M Offline
                                          M Offline
                                          martin_hughes
                                          wrote on last edited by
                                          #20

                                          Slightly OT... But I was wondering, how does Diamon Binding differ/compare to the ADO.Net Entity Framework coming up in VS2008?

                                          Me: Can you see the "up" arrow? User:Errr...ummm....no. Me: Can you see an arrow that points upwards? User: Oh yes, I see it now! -Excerpt from a support call taken by me, 08/31/2007

                                          M 1 Reply Last reply
                                          0
                                          Reply
                                          • Reply as topic
                                          Log in to reply
                                          • Oldest to Newest
                                          • Newest to Oldest
                                          • Most Votes


                                          • Login

                                          • Don't have an account? Register

                                          • Login or register to search.
                                          • First post
                                            Last post
                                          0
                                          • Categories
                                          • Recent
                                          • Tags
                                          • Popular
                                          • World
                                          • Users
                                          • Groups