Type Cast Exception in BusinessBase.Clone

Type Cast Exception in BusinessBase.Clone

Old forum URL: forums.lhotka.net/forums/t/3732.aspx


Patrick.Roeper posted on Wednesday, October 17, 2007

I have a really weird error that I dont believe is due to CSLA, but I am really unsure how to fix this...

The error I am getting is:

Unable to cast object of type 'xplugs.xxxx.BusinessObjects.zzzz' to type 'xplugs.xxxx.BusinessObjects.zzzz'.

 

This is in BusinessBase.cs @

public T Clone()

{ return (T) GetClone(); }

So the clone is getting created correctly, it just cant do the type casting.... I believe this could be because the business object this is happening on is an object that is not referenced by any of our projects directly. Please look at the link below for a simple graph of my project structure....

http://www.xecorporation.com/project_graph.jpg

At any time, my .exe can use reflection to access an unreferenced class library in order to open a form that overrides the base form in our software. The unreferenced library references CSLA... so I can put business objects in there in order to have custom business objects that our software "doesnt know about".

Whenever the UI in the unreferenced library's form calls Clone() on a business object in the unreferenced library, I end up with the exception above.

I was originally getting an "unable to locate assembly" error at...

object temp = formatter.Deserialize(buffer);

... this was due to me not having copied unreferenced.dll into my bin folder after building everything. That is fixed, but now this Crying [:'(]

RockfordLhotka replied on Thursday, November 01, 2007

Odds are that you are running into a "feature" (I call it a bug, but Microsoft disagrees) where the .NET runtime is unable to find assemblies/types from dynamically loaded assemblies without your help.

Typically you encounter this issue when hosting code in COM+ or IE, but it can happen in other cases as well. I don't know for sure that this is your problem, but it is a good bet.

The solution is to use the code for the "serialization workaround" from the EnterpriseServicesHost class in the data portal, as described in Chapter 4.

If you look at that code you'll see that it uses a static constructor to invoke some code once during the lifetime of the appdomain, to hook the event that occurs when .NET is unable to find an assembly. Then all the code does, is to loop through the list of loaded assemblies to find the one .NET couldn't find, and return it. Silly, but there you have it.

(The deep problem is that .NET stores loaded assemblies in multiple lists depending on how they were loaded. In some cases (such as deserialization) the type resolver doesn't look in all the lists, and so doesn't find dynamically loaded assemblies. Fortunately the list of loaded assemblies you get from an AppDomain object is a consolidated list (which is the one you would think deserialization would use...) and so you can easily find and return the 'missing' assembly reference).

I discovered this issue and came up with this workaround way back before .NET 1.0 - it caused all sorts of issues with no-touch deployment, and then loading code into IE. But the issue carries forward to this day...

Patrick.Roeper replied on Thursday, November 01, 2007

Interesting... What steps could I have taken in the debug process to figure this out?

RockfordLhotka replied on Thursday, November 01, 2007

Implement the serialization workaround I mentioned and put a breakpoint in the event handler. If you get there, you know that was the problem :)

 

Rocky

 

 

From: Patrick.Roeper [mailto:cslanet@lhotka.net]
Sent: Thursday, November 01, 2007 4:09 PM
To: rocky@lhotka.net
Subject: Re: [CSLA .NET] Type Cast Exception in BusinessBase.Clone

 

Interesting... What steps could I have taken in the debug process to figure this out?



Patrick.Roeper replied on Friday, November 02, 2007

That did the trick. You da' man Rocky Geeked [8-|]

For any future people stumbling on this thread, this is on page 203 of Expert C# 2005 Business Objects.

Copyright (c) Marimer LLC