(i am posting this for a friend) Application Architecture:
I have an ASP.NET application that contains a number of ASP.NET pages. In addition to the ASP.NET pages, the ASP.NET project contains a VB class called CSRFuncs. I use this class to encapsulate functionality that is used by multiple ASP.NET pages. This class also has a sub-class called Transactional (CSRFuncs.Transactional) that contains functionality which requires transactions. This class inherits from ServicedComponet, and is adorned with the attribute <Transaction(TransactionOption.Required)>. Each method within this class is adorned with the attribute <AutoComplete()>. The methods in CSRFuncs.Transactional often rely on a class library (stand- alone DLL) external to the ASP.NET application. This class library is called ESLEMSNET and contains a number of VB.NET classes. Each class in the DLL is structured in a way similar to the class in the ASP.NET project - that is each class has a sub-class that encapsulates functionality that needs COM+ transactions. The class in question for this case is called Interaction, and it has a sub-class called Transactional (Interaction.Transactional). Interaction.Transactional inherits from ServicedComponent and, just like CSRFuncs.Transactionl, is adorned with the attribute <Transaction(TransactionOption.Required)>. And, each method within Interaction.Transactional is adorned with the attribute <AutoComplete ()>. Problem: I have a method called CreateInteraction which (among other things) tries to assign a value to a class-level private field (integer) called mLastInteractionHistoryId. This field serves as the basis for a read-only property called LastInsertedInteractionHistoryId. The problem I am having is that in Interaction.Transactional when I try to assign a value to the mLastInteractionHistoryId field inside of the CreateInteraction method, the field will not take the value. There is no error at compile-time or run- time, but it is clear that the value is not being assigned. I first determined this by checking the LastInsertedInteractionHistoryId at run- time, and the value was always 0. I then tried making the field Public and accessed it directly at run-time and the value was still always 0. I then stepped through the code with the debugger in VS.NET and could see that I had a non-zero value being assigned to the field, but after the assignment statement, the field would remain set to the value of 0. Call Sequence: The call stack sequence for this functionality starts with a post-back to an ASP.NET page (CRM_CustView.aspx). The code-behind for this ASP.NET page creates an object reference to the CSRFuncs.Transactional class that is part of the ASP.NET project, and then executes a method called StartCall (CSRFuncs.Transactional.StartCall). The StartCall method then creates an object reference to the Interaction.Transactional class which is part of the stand-alone class library DLL and executes the method called CreateInteraction (Interaction.Transactional.CreateInteraction). After CreateInteraction executes, StartCall checks the value of the property Interaction.Transactional.LastInsertedInteractionHistoryId. This is the read-only property that returns the value of the private field mLastInteractionHistoryId. This is the point where the problem manifests itself at run-time as the value returned from the property is always zero. Further Information: In investigating this problem, I tried to narrow down the problem by making a very stripped down class that inherits from ServicedComponent to see if I could isolate the problem. What I found was that even in the most simple form, the field assignment does not work on a class that inherits from ServicedComponent and also adorns the method with <AutoComplete()>. I determined this by commenting out the <AutoComplete()> attribute but still leaving the class to inherit from ServicedComponent. When I commented the line out, the test class worked as expected (assignment to field was successful). I thought "AH HA!!" the problem is with <AutoComplete()>, but I was wrong. When I removed the <AutoComplete()> attributes from both my production methods (StartCall and CreateInteraction) it did not fix the problem I was having. So, though this isn't a work-around, it is an interesting discovery. You can read messages from the DOTNET archive, unsubscribe from DOTNET, or subscribe to other DevelopMentor lists at http://discuss.develop.com.