I am reviewing the priority of a quite dated SC item on the subject and wanted to ask the community for help. The problem may occur when old business class libraries exist in the application folder. By default, XPO tries to load them by the XPObjectType info along with the new versions. This may lead to a conflict at runtime or startup performance degradation. In the latter case, assembly type resolution may come at a cost (see the point 3.5 under How to measure and improve the application's performance).
Why are we hesitating to remove old XPObjectType entries by default?
1. Removing old XPObjectType records affects other apps accessing this database and is serious. Outdated service table records may relate to business class records too (inheritance mapping is in use very often). So, deleting them will lead to foreign key constraint violation. Creating a sophisticated generic solution for this is not easy task.
2. XPObjectType table updates are safe only with the full database and application knowledge. Users possessing this knowledge can use ready options like the ModuleUpdater.UpdateXPObjectType method (SQL Server-specific) shown in the How to: Handle Renamings and Deletions of Business Classes and their Properties article. We also demonstrated a db-server agnostic updater in the aforementioned ticket.
3. We help XAF developers detect this fact by writing log messages. Check out your eXpressAppFramework.log file for the "Resolve the 'DevExpress.ExpressApp.Workflow.v11.1' assembly" and similar messages referring to outdated DevExpress assemblies. Of course, a developer or DBA can preview the XPObjectType table using database engine tools.
4. Old application assemblies living within the new application folder is unexpected in itself. At least, I would instinctively always prefer a fresh Windows install over an update. Even though we are aware of some specific scenarios (e.g., with plugins or locked assemblies), it is still easy to install the new application version into the new folder. This natural action will avoid these risky circumstances completely.
5. Finally, we heard less or almost nothing about this behavior lately. Most likely, this is because an XAF app stores user settings in the database and not in a file system by default and thus the point #4 is simpler.
Your feedback counts!
Regardless of the reasoning above, I want to learn better on how it looks from your side. Please answer two simple questions here in comments or use the https://www.devexpress.com/ask service:
Q1. Did you ever notice negative effects from the outdated type and assembly references in the XPObjectType table?
Q2. If so, describe your problems and use-case scenarios in greater detail. Also, comment on their frequency (e.g., once, every year, etc.) as well as on your current solution implementation and maintenance costs, if any.
In advance, thank you very much for your help! Hopefully, I am not looking this way from your side😜
Hi Dennis,
ReplyDeleteI recently ran into some negative effects with old assemblies in dev/debug with an XAF Web application. Was not throwing any errors but caused extremely slow startup until I figured out I just needed to clean out my bin folder of old assemblies. Had no problems in deployment because I always get rid of old assemblies for Web.
However, I'm getting ready to update a XAF Win application from 17.1 to 17.2 but noticed XPObjectType still has some v16.2 versions in my localdb (and which I still have Dx assemblies installed) so when I ran the app in debug and pulled up the modules window I do see 16.2 and 17.1 assemblies listed from the GAC, although, there are no negative effects that I know of. Still, I would like to make sure that DevExpress updates are as clean as possible. I would rather not have to worry about cleaning up local assemblies on the workstations so I will look into the ModuleUpdater.UpdateXPObjectType method to see if that is something that will work. Just did a quick test of doing a REPLACE() on the AssemblyName column and that kept the 16.2 assemblies from showing in modules window now.
Thanks for your feedback, Randy!
ReplyDeleteNo problem. I also discovered on the Win application that several assemblies were set to Specific Version = false
ReplyDeleteI changed these to true and this also got rid of some additional 16.2 modules which still appeared in the modules window in VS.
We also solved the presence of old assembly.
ReplyDeleteIn WinApp, we have solved it by modifying the AppUpdater. AppUpdater checks for the presence of the old assembly and if it exists than removed it.
Thanks for sharing your solution, Stepan.
DeleteDennis - you already update workflow definitions with the WorkflowDefinitionsUpdater - why not do the same for the XPObjectType table for devex assemblies?
ReplyDeleteThis is rather outdated code. Thanks for pointing this out - we will review it. We hesitate to make such serious updates by default due to the reasons I described above. The most serious problem, IMHO, is when a single database is used by several applications with different versions. See also a similar ticket https://www.devexpress.com/Support/Center/Question/Details/T485124/dashboardobjectdatasource-serializer-fails-to-load-a-data-source-type-when-signed
DeleteAnyway, we will continue monitoring user requests in this regard. In the worst case, I am thinking about making options in the DBUpdater/Application Updater for users to turn on explicitly.
i understand Dennis - however, since DevEx/the framework generates these entries i think it also should maintain them - at least having an option would be good. i guees currently there are two different situations. outdated entries - i fully understand you will/cannot remove them, but the second point, there are used entries which get never updated on major dx version upgrades
DeleteI have many outdated links that aren't required anymore (renamed class names and/or namespaces).
ReplyDeleteHope that cleanup of XPObjectType would increase startup time, because right now I get dozens of AssemblyResolve errors (that are written in my Logs via log4net) and the SQL Statements get also more data than required...
Problem on my side, I'm scared to delete too much, becuase I also use inheritance in some cases...
Is there any statement to cleanup only those that hasn't inheritance? Because as far as I understand, all others aren't that critical, right?