[quoted text, click to view] > The problem is, if you set the ApplicationBase to the plugin directory
> and then set the PrivateBinPath to the bin directory, fusion drops the
> following warning:
>
> [snip]
>
> And since that's exactly where it should be looking, the call to
> CreateInstanceAndUnwrap fails with a FileNotFoundException.
>
> If you try to be clever and set the ApplicationBase to the bin
> directory and the PrivateBinPath to the plugin subdirectory, instead,
> you get a strange SerializationException saying that there is
> insufficient state to deserialize the object.
As it turns out, the solution to this particular problem was that
PrivateBinPath MUST be a relative path. Unfortunately, the
documentation is very abiguous in this regard. (It says that the
PrivateBinPath is combined with the ApplicationBase to probe for
assemblies. It's not immediately obvious whether "combine" means
concatenation, or appending it to the end of the list of places to
probe. I made the mistake of assuming the latter.) If you set an
absolute path, the fusion logs indicate perfectly normal looking
values, and you receive the entirely unhelpful SerializationException.
It took me weeks to find an obscure post on a forum mentioning that
it had to be a relative path, and this could quite easily have been
avoided if the docs had simply said "relative path" instead of what it
currently says. Anyone at Microsoft want to fix that please? Judging
by the forum post I found, I was not the only person to have that
misunderstanding.
Of course, now I am having a new problem. I've gotten the impression
that I cannot, in the primary AppDomain, use references to Types or
Assemblies that are loaded in the secondary AppDomain, because that
would require the primary one to load the assembly as well, which
prevents subsequent unloading. Unfortunately, I needed to be rather
abstract in my method of dealing with plugin classes, so everywhere I
had earlier made use of Type objects, I replaced them with string
parameters containing the fully-qualified classnames, and then did a
Type lookup in the secondary AppDomain with reflection. This seems to
work pretty well, but my CreateInstance method doesn't work.
Debugging in the code shows that the object is successfully created in
the second AppDomain, but trying to return the object to the primary
AppDomain results in a unintentional failed attempt to load into the
primary AppDomain the plugin assembly in which the object resides. I
tried a host of different methods of returning the object, and
everyone results in an error when the return value tries to cross the
AppDomain boundaries. The object derives from
MarshalByReferenceObject. (Although I think the CreateInstance
methods return a value of type object, not sure if that's a problem.
I probably ought to make it that way even if it's not the source of
the problem.) Also, I'm using an abstract base class instead of an
interface. Most plugin systems I looked at used an interface, but an
abstract class was really going to be far more useful to me, and I
assume that ought not to cause problems.