Search

BinaryFormatter fails to deserialize by hmanner

Closed
as External Help for as External

61
0
Sign in
to vote
Type: Bug
ID: 119402
Opened: 6/22/2005 4:32:38 AM
Access Restriction: Public
Duplicates: 98401 115987
10
Workaround(s)
21
User(s) can reproduce this bug
Two problems:

1) The BinaryFormatter always includes version information in the serialized stream even if you set FormatterAssemblyStyle.Simple during serialization. If you try to deserialize the stream after rebuilding the assembly, this will fail, even if you set FormatterAssemblyStyle.Simple during deserialization (fails to load the old assembly version used when creating the serialized stream).

2) When using the BinaryFormatter in a remoting channel, setting the "includeVersions" property on the channel has no effect. The remoting call will always fail if the client and the server uses different versions (different builds) of an assembly for serialization and/deserialization.

Note that there is a similar bug reported (FDBK27794). The findings from Microsoft in that bug is incorrect, this is not just a documentation matter.
Details (expand)
Product Language
English
Version
Visual Studio 2005 Beta 2
Category
Other
Operating System
Windows Server 2003
Operating System Language
US English
Steps to Reproduce
using System;
using System.IO;
using System.Text;
using System.Reflection;
using System.Collections.Generic;
using System.Runtime.Serialization.Formatters;
using System.Runtime.Serialization.Formatters.Binary;
using System.Runtime.Serialization.Formatters.Soap;

#pragma warning disable 1699
[assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyKeyFile("..\\..\\key.snk")]

namespace ConsoleApplication1 {
[Serializable]
class Program {

public int foo = 1;

static void Main(string[] args) {
// Check arguments
bool serialize;
if ((args.Length == 1) && (args[0] == "-d")) {
serialize = false;
} else if ((args.Length == 1) && (args[0] == "-s")) {
serialize = true;
} else {
Console.WriteLine("Must supply either -s or -d option");
return;
}

// Serialize or deserialize
try {
//SoapFormatter formatter = new SoapFormatter(); // The soap formatter works
BinaryFormatter formatter = new BinaryFormatter(); // The binary formatter does not work
formatter.AssemblyFormat = FormatterAssemblyStyle.Simple;
if (serialize) {
using (FileStream stream = new FileStream("result", FileMode.Create, FileAccess.Write)) {
formatter.Serialize(stream, new Program());
}
} else {
using (FileStream stream = new FileStream("result", FileMode.Open, FileAccess.Read)) {
formatter.Deserialize(stream);
}
}
}
catch (Exception e) {
Console.WriteLine(e.ToString());
}
}
}
}
Actual Results
See above.
Expected Results
It must be possible to deserialize streams/use remoting even if assembly versions differ. This bug breaks remoting with binary formatting completetly. It also makes it impossible to use the binary formatter for storing stuff in a database.
File Attachments
0 attachments
Sign in to post a comment.
Posted by vcomrhencke on 7/16/2009 at 7:52 AM
Hi Amadeo,

The three links you posted for hotfix.partners.extranet.microsoft.com seem to currently be broken (DNS can't find server).
Posted by Amadeo Casas - MSFT on 7/2/2009 at 10:42 AM
And the KB article can be found in here:

http://support.microsoft.com/kb/960442
Posted by Amadeo Casas - MSFT on 7/1/2009 at 5:23 PM
This issue will be fixed in the Beta 2 release of .NET 4. The hotfixes for this fix are:


http://hotfix.partners.extranet.microsoft.com/FixDetails.aspx?fixid=372735

http://hotfix.partners.extranet.microsoft.com/FixDetails.aspx?fixid=372736

http://hotfix.partners.extranet.microsoft.com/FixDetails.aspx?fixid=372737

Posted by vcomrhencke on 6/29/2009 at 3:08 PM
4 years have passed... and this is still broken in VS2010 Beta 1 :(
Posted by Jonathan Sawyer on 4/22/2008 at 2:33 AM
http://dotnet.org.za/jonno/archive/2008/02/28/binaryformatter-the-located-assembly-s-manifest-definition-does-not-match-the-assembly-reference.aspx

I wrote a blog post about this a while back that provides an effective workaround.
Posted by rksiii on 4/21/2008 at 1:21 PM
Still not fixed in the latest VS2008
Posted by Kanaida on 1/21/2008 at 3:30 PM
This is great... finally I had a great native way of sending business objects in one call, with one dll, compressed and all over web services and now this. I totally dont get this. If I serialize, compress then submit to a web service method, decompress, deserialize it shows up just fine in the web service. no compromise. But i try to do that in the other direction to the client with a 20MB dataset that is now 1.03MB the deserializer gives me that error. It figures the fountain of youth does not come without consequence.
Posted by Anonymous2619 on 12/22/2007 at 5:25 AM
As of .NET Framework 3.5 it's still not fixed. See validation #19 for simple reproduction.
Posted by Arjan Keene on 4/7/2007 at 8:23 AM
Issue is definitely not fixed, indeed. And that is not in any scenario; a rebuild implies that a previously binary formatted file with e.g. a Collections<T> derivative cannot be deserialized anymore. It is curious that this was overlooked - given the primary requirement of compatibility (yes, some of us do care about that one ;-) on the one hand, and the pushing force for generics in code analysis etc. in VS2005 on the other hand.
Posted by Chris Holt on 3/23/2007 at 6:22 AM
Not sure why this was closed. This issue still exists even after VS2005 SP1. This was never fixed. Is this only fixed in .NET 3.0 and above?
Posted by Microsoft on 3/1/2007 at 9:42 AM
We are in the process of considering this bug for the next release.

Daniel Roth
Program Manager
Posted by Microsoft on 10/25/2005 at 7:18 PM
This issue has been reactivated as we begin planning for the next version of Visual Studio and the .NET Framework. Over the coming months we will reconsider feedback that was previously postponed. We welcome your comments and participation in this process. See http://blogs.msdn.com/productfeedback/archive/2005/10/21/483563.aspx for more information.

- The Developer Division
Posted by Microsoft on 9/26/2005 at 1:02 PM
Thank you very, very much for bringing this to our attention, for following up, and for not giving up after two bug resolutions. I think this is a great example of the value of the MSDN Feedback program. You have indeed uncovered a serious problem with Version Tolerant Serialization and Generics. Unfortunately, Whidbey is pretty much completely closed down right now, and it is impossible to check in a fix even for a bug of this magnitude, which is why I am forced to resolve this as Postponed. However, be assured that we are treating this issue very seriously and are now in the process of discussing alternative delivery vehicles for this fix (e.g. the possibility of making a patch available through Product Support Services.) In the meantime, please use assembly binding redirection (http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpguide/html/cpconassemblybindingredirection.asp) as a workaround.
Thank you again for the time you invested in reporting this problem,
-- Eugene Osovetsky, Program Manager, XML Messaging / Serialization
Posted by hmanner on 9/23/2005 at 7:23 AM
I believe that the problem has to do with generics!

First some short answers to your questions:

- The pure serialization problem is NOT solved when it comes to generic types. Try changing my previous sample code so that it serializes a List<Program> instead of just a single Program.
- See below for exception details on the remoting problem
- None of the assemblies are in the GAC
- I do not have multiple assembly versions in the application directory

I have created a small client-server solution which reproduces the remoting problem (see attached file). NOTE: I was not able to reproduce the problem in this small solution until I made the server return a generic list!

The solution contains 3 projects:

1) A server exe
2) A client exe
3) A shared library assembly containing a class sent between the client and the server

Included in the solution are binaries from two builds:

1) The directory Client\bin\Debug contains the same version of the shared assembly as the server.
2) The directory Client\bin\OldDebug contains an older version of the shared assembly (I just saved the directory from an older build).

- Start the server exe in a console window.
- Run the client from the Debug directory in another console window, this should work fine.
- Now try running from the OldDebug directory - this fails with the following exception (note that the OldDebug directory contains version 1.0.2092.22710, not 1.0.2092.22725):

===
System.IO.FileLoadException: Could not load file or assembly 'Common, Version=1.0.2092.22725, Culture=neutral, PublicKeyToken=80289c6304416642' or one of its de pendencies. The located assembly's manifest definition does not match the assembly reference. (Exception from HRESULT: 0x80131040) File name: 'Common, Version=1.0.2092.22725, Culture=neutral, PublicKeyToken=80289c6304416642'
at System.Runtime.Remoting.Proxies.RealProxy.HandleReturnMessage(IMessage reqMsg, IMessage retMsg)
Posted by Microsoft on 9/22/2005 at 2:14 PM
Unfortunately, we cannot recreate the problem on our end. Please answer the following questions:
- Does standalone serialization work fine in RC1, without remoting?
- What is the exception you are getting in Remoting with the RC1 bits? Is it " System.Runtime.Serialization.SerializationException: Unable to find assembly" or is it "System.InvalidCastException: Return argument has an invalid type."?
- Is it possible that you have multiple versions of the same assembly available on the receiving / deserializing side (either in the GAC or in your application directory)?
- Also, it would help a lot if you attached a Remoting (and not just a Serialization) repro, especially if the answer to the first question is "Yes".
Please reactivate the bug when you've supplied the additional information.
Posted by hmanner on 9/22/2005 at 5:44 AM

No, that is not the scenario at all. Both client and server are running .NET 2.0!

- We have a client-server application
- Both client and server are built with VS 2005
- We use .NET remoting for communication
- We use binary formating over tcp and/or http channel
- We are setting includeVersions="false", strictBinding="false" and typeFilterLevel="Full" on the binary formatter for the channel
- We have som custom classes in an assembly shared by both the client and the server
- The custom classes are marked as [Serializable] and implement the ISerializable interface
- The custom classes are passed as arguments between the client and the server

Now. If we build the client and the server separately in two consecutive (re)builds, the shared assembly will get a different version number on the client and the server. If we now run the client and the server together, the deserialization of the custom classes will fail on the client because the client can not find the assembly version (of the shared assembly) that the server is using.

This means that it will be impossible to build a new version, like a patch, of the server (still with VS2005), and deploy it at customer sites without simultaneously rebuilding and upgrading the clients as well (to make sure they get the same version number of the shared assembly).

This is unacceptable when we have thousands of clients!!!

Note that this was not a problem in VS2003/.NET 1.1. Back then the shared assembly did not have to be of the same version on the client and the server side, because the full version info was stripped from the serialized stream by the formatter.
Posted by hmanner on 9/22/2005 at 5:43 AM
No, that is not the scenario at all. Both client and server are running .NET 2.0!

- We have a client-server application
- Both client and server are built with VS 2005
- We use .NET remoting for communication
- We use binary formating over tcp and/or http channel
- We are setting includeVersions="false", strictBinding="false" and typeFilterLevel="Full" on the binary formatter for the channel
- We have som custom classes in an assembly shared by both the client and the server
- The custom classes are marked as [Serializable] and implement the ISerializable interface
- The custom classes are passed as arguments between the client and the server

Now. If we build the client and the server separately in two consecutive (re)builds, the shared assembly will get a different version number on the client and the server. If we now run the client and the server together, the deserialization of the custom classes will fail on the client because the client can not find the assembly version (of the shared assembly) that the server is using.

This means that it will be impossible to build a new version, like a patch, of the server (still with VS2005), and deploy it at customer sites without simultaneously rebuilding and upgrading the clients as well (to make sure they get the same version number of the shared assembly).

This is unacceptable when we have thousands of clients!!!

Note that this was not a problem in VS2003/.NET 1.1. Back then the shared assembly did not have to be of the same version on the client and the server side, because the full version info was stripped from the serialized stream by the formatter.
Posted by Microsoft on 9/21/2005 at 7:42 PM
We cannot seem to repro the problem in 2.0. We understand the scenario to be clients running in 1.1 and server running in 2.0 (RC1)
It would be great if you could provide us more information about the issue.
1. Is the exception is the same as before?
2. Does the exception occur on the client (1.1) or the server (2.0)?

Thanks
Sowmy Srinivasan
Posted by Microsoft on 9/21/2005 at 5:50 PM
Can you please let us know if the exception occur on the 1.1 or the 2.0 side?
Thanks
Sowmy Srinivasan
Posted by hmanner on 9/21/2005 at 9:51 AM
I have tested this in RC1, and the problem is still there in the remoting scenario! You can not run an old client against a server which has newer versions of shared assemblies for serialization.

Again, this makes it impossible to patch a server application without simultaneously patching all client machines.

This MUST be fixed - this is a very serious issue in a real world scenario with thousands of clients.
Posted by Microsoft on 7/11/2005 at 9:55 AM
This will be fixed in RTM
Posted by Microsoft on 7/7/2005 at 5:55 PM
The Microsoft Sub-status is now "Working on solution"
Posted by hmanner on 7/7/2005 at 12:17 AM
I have to point out how very serious this issue is. When using remoting in a client-server scenario with up to 10000 clients it must (MUST!) be possible to upgrade/patch the server application without having to modify all the clients. This issue makes this practically impossible because it requires that the client and the server has the same versions of common assemblies containing serializable types, meaning that all 10000 clients must be updated as well.

This simply must be fixed, so that it works like in .NET Framework 1.1. And it is absolutely not an option to register assemblies in the GAC on the clients, we do not even have permission to do so.

Now to your question: In the remoting case the error just changes when registering the affected assemblies in the GAC, there is thus still a problem. The error changes from:

System.Runtime.Serialization.SerializationException: Unable to find assembly

to

System.InvalidCastException: Return argument has an invalid type.
at System.Runtime.Remoting.Proxies.RealProxy.ValidateReturnArg(Object arg, Type paramType)
at System.Runtime.Remoting.Proxies.RealProxy.PropagateOutParameters(IMessage msg, Object[] outArgs, Object returnValue)
at System.Runtime.Remoting.Proxies.RealProxy.HandleReturnMessage(IMessage reqMsg, IMessage retMsg)
at System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke(MessageData& msgData, Int32 type)
Posted by Microsoft on 7/6/2005 at 12:49 PM
Does the GACing workaround not work for remoting channel?
THanks
Sowmy
Posted by hmanner on 7/6/2005 at 5:12 AM
Yes it does. If any version of the assembly is in the GAC it works fine. And I mean any version, it does not have to be either the version that created the serialized stream, or the version trying to deserialize the stream. It can be just any old version of the assembly.

But I should not have to GAC it to make it work, should I?

And what about the corresponding problem in the remoting channel?
Posted by Microsoft on 7/6/2005 at 1:25 AM
Can you please try GACing the assembly and see if that works for you?
Thanks
Sowmy
Posted by Microsoft on 6/30/2005 at 9:25 AM
Thank you for submitting this issue. It has been assigned to a product team representative who will respond with comments shortly.

Elliot Rapp
Xml Messaging team
Posted by hmanner on 6/30/2005 at 4:28 AM
Som more information: it looks like the problem only appears when the assembly has a strong name. I have included some sample code (see below) which can be used for reproducing the problem:

1) Build the sample as a console application (note the AssemblyVersion and AssemblyKeyFile attributes!)
2) Run the program with option -s, this will save a serialized stream to disk
3) Rebuild the project so that the application gets a new revision number
4) Run the program with option -d, this will deserialize the stream - this will throw an exception

Note that it works fine if you replace the binary formatter with the soap version.
Posted by hmanner on 6/29/2005 at 4:58 AM
How do you mean "steps to reproduce needed"? See below! I suspect that the remoting problem #2 is caused by the same problem as #1. See below for reproducing #1.
Posted by Microsoft on 6/28/2005 at 9:19 PM
The Microsoft Sub-status is now "Steps to Reproduce needed"
Sign in to post a workaround.
Posted by hmanner on 1/6/2006 at 1:47 AM
Dont use any formatter.

Use XML formatting methods to objects and pass xml content between client and server.
Posted by hmanner on 1/22/2006 at 3:21 AM
We are currently using an assembly resolver, ignoring the version of the assemblies.

Regarding the last posted workaround...using XML...well...sigh...now that's what I call a workaround...hehe.



See the AppDomain.AssemblyResolve event.
Posted by hmanner on 3/10/2006 at 12:12 PM
My error was:
Could not load file or assembly 'System.Runtime.Serialization, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089' or one of its dependencies. The system cannot find the file specified."
I started getting it right after uninstalling the Visual Studio Extensions for WinFX beta 1.
Repaired my visualstudio /.net2 installations still same error.

This is the most generic workaround ever and probably opens up major security holes given the lines commented out, but I'll be transfered to my new pc on Monday. I commented out the following lines in my global web.config file.
Note: I would not suggest this except for a very slacked out alternative, but my web projects compile now.


                <!--<add assembly="System.Runtime.Serialization, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089, processorArchitecture=MSIL" />-->
                <!--<add assembly="System.Security.Authorization, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089, processorArchitecture=MSIL" />-->
                <!--<add assembly="System.ServiceModel, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />-->




<!--<add name="ServiceModel" type="System.ServiceModel.Channels.HttpModule, System.ServiceModel, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />-->
Posted by Dave Midgley on 1/22/2007 at 1:25 AM
We have had serious problems with this, and finally raised an MSDN incident and it has been confirmed as a problem, although it is not known when a fix will be available, or whether the fix, when it comes, will allow generic objects serialised without the fix to be deserialised by code with the fix. They also confirmed that the AssemblyResolve event was a valid workaround, and that it shouldn't have any adverse effects. They pointed out that the event only needs to be subscribed to once per app domain, as long as the program only has one app domain the subscription can be put in Main regardless how many assemblies or threads are doing serialisation.
For the benefit of others in the same boat, this is how I think the event handler should look (if anyone know better I'd be interested):

System.Reflection.Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args)
{
    // args.Name looks like this:
    // "<AssemblyName>, Version=<major>.<minor>.<build>.<revison>, Culture=neutral, PublicKeyToken=<16 hexit number>"
    // We need to parse it to extract the version number and the simple name
    string versionStr = args.Name.Substring(args.Name.IndexOf("=") + 1);    // Don't look for "Version" it may vary by locale
    versionStr = versionStr.Substring(0, versionStr.IndexOf(","));
    string simpleName = args.Name.Substring(0, args.Name.IndexOf(','));

    // Load the assembly using just the name
    AssemblyName assemblyName = new AssemblyName();
    assemblyName.Name = simpleName;
    Assembly assembly = Assembly.Load(assemblyName);

    // Now replace the assembly's version number with the required version and return it.
    assembly.GetName().Version = new Version(versionStr);
    return assembly;
}
Posted by Unregistered User on 1/27/2007 at 1:02 PM
I built a dll that is simply a generic class I use to serialize/deserialize when transfering over named pipes. Since all projects reference the same library, I am not getting this error.


Below is all that exists in the project and then the server projects (multiple windows services) reference this project. Everyone is using the same version so it satisfies the assembly verification when deserializing

''' <summary>
''' Object used to transfer between server/client
''' </summary>
''' <remarks>Contains the action, data and session GUID</remarks>
<Serializable()> Public Class TransferObject

    Public Action As String
    Public transferObject As Object
    Private reqID As Guid

    Public ReadOnly Property requestID() As Guid
        Get
            Return reqID
        End Get
    End Property
    Public Sub New()
        reqID = Guid.NewGuid
    End Sub

End Class

The above has allowed me to transfer this generic object over a TCP connection, then from service to service via named pipes.

Hope this helps!
Posted by murfffi on 4/13/2007 at 3:45 AM
If the type and all its members are in the current assembly, you attach the following custom Binder to the BinaryFormatter (using the Binder property).

/// <summary>
/// This binder will ignore the assembly information, thus allowing deserializing from different assembly versions.
/// </summary>
private class SimpleBinder : System.Runtime.Serialization.SerializationBinder
{
public override Type BindToType(string assemblyName, string typeName)
{
    //assemblyName ignored.
    return Type.GetType(typeName);
}
}

This solution can be used, if you don't want to alter the assembly resolving of the whole AppDomain. The Binder implementation can be easily modified, so it can load other assemblies.
Posted by BobD4 on 8/9/2007 at 9:35 AM
Hooking into the AssemblyResolve event works for my. However, make sure to use the AssemblyName class to parse the full name of the assembly, rather than implementing your own parsing logic.
Posted by Debugger on 8/13/2008 at 11:54 AM
I am still facing problems in non-Generic types. Using custom binder doesn't help even if all the types are resolved i.e.

private class SimpleBinder : System.Runtime.Serialization.SerializationBinder
{
public override Type BindToType(string assemblyName, string typeName)
{
    newAssemblyName = "Client.PersonalArchivalEngine.Base";
    return Type.GetType(newAssemblyName,typeName);
}
}

I still get this error message from the given stack trace given below...

Could not load file or assembly 'Client.PersonalArchivalEngine.Base, Version=1.0.3056.37064, Culture=neutral, PublicKeyToken=null' or one of its dependencies. The located assembly's manifest definition does not match the assembly reference. (Exception from HRESULT: 0x80131040)</Message>
    <StackTrace> at System.Reflection.Assembly._nLoad(AssemblyName fileName, String codeBase, Evidence assemblySecurity, Assembly locationHint, StackCrawlMark& stackMark, Boolean throwOnFileNotFound, Boolean forIntrospection)
at System.Reflection.Assembly.nLoad(AssemblyName fileName, String codeBase, Evidence assemblySecurity, Assembly locationHint, StackCrawlMark& stackMark, Boolean throwOnFileNotFound, Boolean forIntrospection)
at System.Reflection.Assembly.InternalLoad(AssemblyName assemblyRef, Evidence assemblySecurity, StackCrawlMark& stackMark, Boolean forIntrospection)
at System.Reflection.Assembly.InternalLoad(String assemblyString, Evidence assemblySecurity, StackCrawlMark& stackMark, Boolean forIntrospection)
at System.Reflection.Assembly.Load(String assemblyString)
at System.UnitySerializationHolder.GetRealObject(StreamingContext context)
at System.Runtime.Serialization.ObjectManager.ResolveObjectReference(ObjectHolder holder)
at System.Runtime.Serialization.ObjectManager.DoFixups()
at System.Runtime.Serialization.Formatters.Binary.ObjectReader.Deserialize(HeaderHandler handler, __BinaryParser serParser, Boolean fCheck, Boolean isCrossAppDomain, IMethodCallMessage methodCallMessage)
at System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.Deserialize(Stream serializationStream, HeaderHandler handler, Boolean fCheck, Boolean isCrossAppDomain, IMethodCallMessage methodCallMessage)
at System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.Deserialize(Stream serializationStream)</StackTrace>

AssemblyResolve works fine.

I wonder why this bug hasn't been fixed till now.
Posted by Xiaoxing Zhu on 10/15/2008 at 4:51 AM
The workaround of AssemblyResolve works for deserialization. But after the object is deserialized, it cannot be casted to the required type. (Seems the version change also fails this). How are you guys working around this?
Posted by Daniele Mancini on 9/4/2009 at 3:18 AM
As stated in other comments, using a SerializationBinder is a way to fix the issue. Since none provided a sample here it is one.

/// <summary>
/// Class used to allow for deserialization of types hosted in assemblies having different versions.
/// </summary>
/// <remarks>The binder will always match requested assembly with currently available one, without knowing if this action is legal or not.</remarks>
private sealed class VersionAgnosticSerializationBinder : System.Runtime.Serialization.SerializationBinder
{
        /// <summary>
        /// When overridden in a derived class, controls the binding of a serialized object to a type.
        /// </summary>
        /// <param name="assemblyName">Specifies the <see cref="T:System.Reflection.Assembly"/> name of the serialized object.</param>
        /// <param name="typeName">Specifies the <see cref="T:System.Type"/> name of the serialized object.</param>
        /// <returns>
        /// The type of the object the formatter creates a new instance of.
        /// </returns>
        public override Type BindToType(string assemblyName, string typeName)
        {
                Type type = Type.GetType((System.Reflection.Assembly.CreateQualifiedName(assemblyName, typeName)));

                if (type == null)
                {
                        //A full name was passed, we need the simple one!
                        string simpleAssemblyName = assemblyName.Split(',').FirstOrDefault();

                        if (string.IsNullOrEmpty(simpleAssemblyName))
                                throw new InvalidOperationException("Cannot retrieve assembly name from string '" + assemblyName + "'");

                        System.Reflection.Assembly currentAssembly = AppDomain.CurrentDomain.GetAssemblies().FirstOrDefault((System.Reflection.Assembly assembly) => { return (assembly.GetName().Name.Equals(simpleAssemblyName)); });

                        if (currentAssembly == null)
                                throw new InvalidOperationException("The requested assembly '" + simpleAssemblyName + "' was not found");

                        type = currentAssembly.GetType(typeName);
                }

                if (type == null)
                        System.Diagnostics.Debug.WriteLine("Cannot bind requested type '" + string.Format("{0}, {1}", assemblyName, typeName), GetType().ToString());

                return type;
        }
}