I'm still trying to find a way how to correctly implement the XPWeakReference mechanism in my particular case. I have read all the available issues related to this topic but failed to find a complete guidance how to proceed with this task.
So I tried to follow your code and implement similar behaviour as in your Audit Trail Module. However with no success.
I exctracted what I finished with into an example project (can be found in attachement).
In my case, I'm trying to define persistent class Comment and implement weak reference mechanism to any other persistent class in project. In this example this classes are Event and WebSite. I would like to be able to implement a regular "add comment" feature to any object of this two types.
Could you help me in this matter and point out what I did wrong in my example.
Thanks a lot for your help.
Josef
Disclaimer: The information provided on DevExpress.com and affiliated web properties (including the DevExpress Support Center) is provided "as is" without warranty of any kind. Developer Express Inc disclaims all warranties, either express or implied, including the warranties of merchantability and fitness for a particular purpose. Please refer to the DevExpress.com Website Terms of Use for more information in this regard.
Confidential Information: Developer Express Inc does not wish to receive, will not act to procure, nor will it solicit, confidential or proprietary materials and information from you through the DevExpress Support Center or its web properties. Any and all materials or information divulged during chats, email communications, online discussions, Support Center tickets, or made available to Developer Express Inc in any manner will be deemed NOT to be confidential by Developer Express Inc. Please refer to the DevExpress.com Website Terms of Use for more information in this regard.
Hello Josef,
Thank you for your question. We have consulted with our XPO developers and come to the conclusion that the use of XPWeakReference for your particular case is not the best solution.
Instead, we recommend you keep the Comment class as a abstract class and then create its specific descendants (e.g., TaskComment, UserComment, XXXComment, etc.). The How to establish association from one class to many classes example describes a similar scenario as well.
On the other hand, you could benefit from using Domain Components instead of persistent objects. For instance, take a look at the INotes interface from our XCRM demo. It is added to many other domain components to provide the notes functionality. You have exactly the same case here. I just wanted to add that these are just our thoughts on how to implement your scenario. Of course, the final decision is fully up to you.
I hope you find this information helpful.
Thanks,
Dennis
Thank you for your response. The first option seems to be overcomplicated and development expensive. I would need to create new class (base Comment descendant) for each new comment-aware class I create. I also need to be able to work with all the comments in unified way.
The second option looks interesting (never tried DomainComponents before). Unfortunatelly, I need to work with Comments also with non-XAF environment, where only regular UnitOfWork is available (no ObjectSpaces).
That is why I would like to ask, what is in your opinion the main reason not to use the XPWeakReference way. From my point of view the XPWeakReference implementation in the frame of Audit Trial Module as almost the same scenario, as the one I mentioned above.
Thanks a lot.
Josef
Hello Josef,
XPWeakReference is only useful for a limited number of scenarios and we do not recommend its use without a real need. That is the only reason why this class is not documented except for a standard reference: http://documentation.devexpress.com/#XPO/clsDevExpressXpoXPWeakReferencetopic
XPWeakReference can be used in a scenario (e.g. audit) when you never have to go back to the referenced object or have to do this very rarely.
In our opinion, your particular scenario is totally different (because in our opinion comments are supposed to be visible and thus you will have to go back to the reference object), so XPWeakReference should not be used here. Otherwise, it will not only be unnatural, but also ineffective from the performance POV.
As I already mentioned above, the best solution for your requirement is creating a base Comment class and creating descendants from it, if necessary. I do not think that you will have to create a descendant for each comment-aware class because the base functionality of Comment can be sufficient in most cases. It is also quite easy and straightforward to implement this solution as you will require making a simple 1-M association between two classes. So, it is not quite clear why you think that this option is "overcomplicated and development expensive".
Another good solution is using DC, but as I see it may really not meet you needs, because you have no knowledge of IObjectSpace. However, I wanted to note that DC can be used in non-XAF applications and ObjectSpace is technically just a wrapper around UnitOfWork:
http://documentation.devexpress.com/#Xaf/CustomDocument3305
Well, we do not have other options at the moment, and I wanted to note that the final decision is up to you as we cannot dictate a solution. However, if you decide to use XPWeakReference in this scenario, I am afraid we will not be responsible for any problems it may bring, and it will be completely up to you to resolve them (I elaborated more on why this is earlier).
Thanks,
Dennis
Hello Denis.
Thanks a lot for your comprehensive answer and explanation. Facing your reasonable arguments (as your support never failed me yet) I'm going to follow your advice to use abstract class BaseComment and inherit classes for particular "comment-aware" classes.
However, is there a way in XAF, how to display and work with all the comment-based classes in single ListView at once?
Thanks a lot for a tip.
Josef
>>abstract class BaseComment and inherit classes
It is not necessary to make it abstract because as I mentioned above, it may be pretty good as is for most other classes. I mean that type-specific comments will likely be exceptions. But once again, I do not insist ;-)
As for displaying all this stuff in a single ListView, guess what - that is possible:-)
The http://documentation.devexpress.com/#Xaf/CustomDocument2797 help article sheds more light on this. I hope you find it helpful.
Thanks,
Dennis
The first solution you are proposing is exactly what I'm looking for. However (probably I missing something), I still can not realize, how to implement associations between classes (Event-Comments and WebSite-Comments in case of my example). I tried something but I got following exception:
CommentExample.Module.BusinessObjects.Event.Comments is not a collection property. It should be labeled with AssociationAttribute and be of the XPBaseCollection descendant type. Probably, you use GetCollection in the situation where GetList should be used.
What is your idea of making relation between Comment and all the other classes without being forced to implement all the possible associations on both sides of all pairs?
Thanks
Josef
I forgot to enclose my second example, where I tried what you proposed.
Josef,
The GetCollection method is supposed to be used with associated collections only.
Would you please review the How to establish association from one class to many classes example? I suggested it in my first reply to you because it demonstrates how to implement a collection of comments only once, instead of defining it for each persistent object.
I hope you find this information helpful.
Thanks,
Dennis
I see. Unfortunately, I declined this variant in the beginning already. I thought there is another way.
Using this approach you described, I would need to attach Comment to very general abstract class to affect all the descendant classes I wish to make comment-aware.
To have Comments collection available in almost all the classes (even if such a relation have no sense) could be confusing, but this is an aspect I could live with. The major disadvantage in my opinion (correct me please if I'm wrong) is on the database side, where another level of table in Mapping Inheritance will appear, what brings another JOIN into each DB request (affecting performance). I'm familiar wiht the MapInheritanceType.ParentTable option, but this is not a right solution in my particular case.
I feel we are running out of options. Sorry for my bothering and thanks again for your patience.
Josef
What do you think about this approach (CommentExample3.zip)? Could it be a correct way? I just still can't manage to make the propagated Comments collection (in Event and WebSite classes) behave in XAF application as expected.
Josef
Hi Josef,
>>The major disadvantage in my opinion (correct me please if I'm wrong) is on the database side, where another level of table in Mapping Inheritance will appear, what brings another JOIN into each DB request (affecting performance)
In my opinion, it is a common prejudice that negatively affects developers and their design decisions. Yes, it will bring another JOIN, but XPO is optimized to perform DB queries as soon as possible and thus it will not affect you in any way.
If you ever experience any real performance problems with this, please let us know. However, I do not insist on using this solution and it is fully up to you to decide.
>>What do you think about this approach (CommentExample3.zip)? Could it be a correct way?
Yes, using aggregation is another way to accomplish this task. You will be probably pleased to hear that we use this design pattern in our Domain Components (DC) when emulating multiple inheritance.
I have slightly modified your project to make it work as you expected. Please let me know if this was helpful.
Thanks,
Dennis
Bingo! That is exactly a solution I've been looking for. Thanks a lot for your help.
Welcome, Josef;-)
Regards,
Dennis
=================================
Please let us know what you think of our frameworks and other DevExpress products by rating them on the Visual Studio Gallery:
eXpressApp Framework
eXpress Persistent Objects
=================================