473,402 Members | 2,050 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,402 software developers and data experts.

Assembly lookup , GAC and plugins

Hello group.

I have an app which can load "plugins" assemblies that are described
in the registry (each registry entry gives the full path to the plugin
..dll file). The plugins may be anywhere on the disk.

Each plugin defines a class which implements an interface known to the
app. The main app loads the plugin with Assembly.LoadFrom and then
uses Assembly.GetTypes() and Type.FindInterface to find the concrete
types in the plugin that implements the interface. An object of this
concrete type is then constructed by reflection (ConstructorInfo ->
Invoke).

All of this is rather easy stuff. Now a plugin and the main app
depends both on an utility assembly (let's call it Utils.dll).
Utils.dll and MainApp.exe are strong-named, Plugin.dll is not.

My problem is that the main app and the plugin are compiled at
different times and therefore reference different versions of
Utils.dll :
MainApp.exe --> Utils.dll V 1.0.0.0
Plugin.dll --> Utils.dll V 1.0.1.0

Plugin.dll is in a directory unrelated to MainApp. Therefore, I must
put Utils.dll V 1.0.1.0 in the GAC because Plugin.dll's path is not
looked for when loading the plugin.

Now, I can put Utils.dll v 1.0.0.0 either in MainApp directory, either
in GAC. But in both cases, I got a FileNotFoundException : "File or
assembly name Utils, or one of its dependencies, was not found" when
calling Assembly.LoadFrom("MyPlugin\Plugin.dll").
It seems that, although Utils.dll is strong-named, since Utils.dll V
1.0.0.0 is already loaded in the AppDomain, the GAC is not looked for
the correct version of Utils (1.0.1.0) and therefore loading fails.

Has anyone seen such a behaviour, and what would be the workaround?
I've got no trace in fuslogvw (why??).
Thanks,
Arnaud
MVP - VC

PS : Utils.dll has no dependencies itself (except on the framework).
There is no publishher file and no application configuration file
(since plugins may be distributed after the app)
Jul 21 '05 #1
4 2842
My problem is that the main app and the plugin are compiled at
different times and therefore reference different versions of
Utils.dll :
MainApp.exe --> Utils.dll V 1.0.0.0
Plugin.dll --> Utils.dll V 1.0.1.0

Plugin.dll is in a directory unrelated to MainApp. Therefore, I must
put Utils.dll V 1.0.1.0 in the GAC because Plugin.dll's path is not
looked for when loading the plugin.

Now, I can put Utils.dll v 1.0.0.0 either in MainApp directory, either
in GAC. But in both cases, I got a FileNotFoundException : "File or
assembly name Utils, or one of its dependencies, was not found" when
calling Assembly.LoadFrom("MyPlugin\Plugin.dll").
It seems that, although Utils.dll is strong-named, since Utils.dll V
1.0.0.0 is already loaded in the AppDomain, the GAC is not looked for
the correct version of Utils (1.0.1.0) and therefore loading fails.

If the plugin is compiled against utils.dll, v1.0.0.0 and utils is signed
with a strong name, then the runtime will load it if it can find it. As long
as the assembly is signed the runtime can load two different versions of the
same dll. The runtime can even load the same version of the dll twice, one
in the Load context, and another copy in the LoadFrom context (although this
is usually not what you want to happen).

Have you tried signing the plugin.dll to see if this changes the behavior? I
would not expect it too, but there may be other things going on.
Has anyone seen such a behaviour, and what would be the workaround?
I've got no trace in fuslogvw (why??).

You can install a publisher policy for Utils.dll that specifies that the
latest version of the dll should always be the one used - I don't know if
this is what you want but it would avoid the problem you're seeing.

Regardless, you could subscribe to the AssemblyResolve event and use that to
manually locate the Utils.dll for the plugin.
Jul 21 '05 #2
"David Levine" <no****************@wi.rr.com> wrote in message news:<OX**************@TK2MSFTNGP15.phx.gbl>...
My problem is that the main app and the plugin are compiled at
different times and therefore reference different versions of
Utils.dll :
MainApp.exe --> Utils.dll V 1.0.0.0
Plugin.dll --> Utils.dll V 1.0.1.0

Plugin.dll is in a directory unrelated to MainApp. Therefore, I must
put Utils.dll V 1.0.1.0 in the GAC because Plugin.dll's path is not
looked for when loading the plugin.

Now, I can put Utils.dll v 1.0.0.0 either in MainApp directory, either
in GAC. But in both cases, I got a FileNotFoundException : "File or
assembly name Utils, or one of its dependencies, was not found" when
calling Assembly.LoadFrom("MyPlugin\Plugin.dll").
It seems that, although Utils.dll is strong-named, since Utils.dll V
1.0.0.0 is already loaded in the AppDomain, the GAC is not looked for
the correct version of Utils (1.0.1.0) and therefore loading fails.

If the plugin is compiled against utils.dll, v1.0.0.0 and utils is signed
with a strong name, then the runtime will load it if it can find it. As long
as the assembly is signed the runtime can load two different versions of the
same dll.

That's what I thaugt and that's why I don't understand the behaviour I
get. I'm gonna do additionnal tests.
The runtime can even load the same version of the dll twice, one
in the Load context, and another copy in the LoadFrom context (although this
is usually not what you want to happen). What is exactly a Load Context? Ther is very few information on the
subject. All I got in MSDN is KB 327435 (but this doesn't apply to
..NET 1.1 and VS2003, does it?) and the cryptic sentence in
Assembly.Load documentation :
"The Load methods use the default load context, which records the
assembly name and assembly instance information for the set of
assemblies that is the transitive closure of the assemblies referenced
by a managed application" Huhhh????? How does it help with finding a
new assembly?

Have you tried signing the plugin.dll to see if this changes the behavior? I
would not expect it too, but there may be other things going on. I will try asap.
Has anyone seen such a behaviour, and what would be the workaround?
I've got no trace in fuslogvw (why??).

You can install a publisher policy for Utils.dll that specifies that the
latest version of the dll should always be the one used - I don't know if
this is what you want but it would avoid the problem you're seeing.

Regardless, you could subscribe to the AssemblyResolve event and use that to
manually locate the Utils.dll for the plugin.


Now, this is interesting! I wasn't aware of this event. I will use it
in my plugin loader mechanism. I could consider that all dependencies
of a plugin are located in the plugin directory itself (which will
also prevent me from clobbering the GAC with various versions of
utils.dll).

Thanks for the hints.

Arnaud
MVP - VC
Jul 21 '05 #3
>> The runtime can even load the same version of the dll twice, one
in the Load context, and another copy in the LoadFrom context (although
this
is usually not what you want to happen). What is exactly a Load Context? Ther is very few information on the
subject. All I got in MSDN is KB 327435 (but this doesn't apply to
.NET 1.1 and VS2003, does it?) and the cryptic sentence in
Assembly.Load documentation :


The KB article does not really address the Load versus LoadFrom context.

What it boils down to is that the runtime's fusion layer keeps multiple
internal lists of assemblies. Assemblies in the Load context can
automatically bind to other assemblies in the Load context, and references
to types defined in those assemblies can be resolved by the runtime without
external assistance. Assemblies in the LoadFrom context cannot automatically
bind to other assemblies in the LoadFrom context (at least, not as far as I
know), and references to types must be manually resolved.

What this means is that if Assembly a is in the LoadFrom context and it has
a static reference to asm B (e.g. in the same directory as asm A but not
loaded into fusion), then unless asm B is in a directory where fusion can
locate it automatically (e.g. the GAC, or the appbase) it will not load, and
will need to manually loaded by your own code (hence you need to hook the
AssemblyResolve event).

Further, if your code accesses a type defined in an assembly in the LoadFrom
context, then when the runtime resolves that type it will have to access the
assembly, but because it is not in the Load context it will generate another
AssemblyResolve event even though the correct assembly is already loaded in
the LoadFrom context.
"The Load methods use the default load context, which records the
assembly name and assembly instance information for the set of
assemblies that is the transitive closure of the assemblies referenced
by a managed application" Huhhh????? How does it help with finding a
new assembly?

That fancy terminology means something along the lines of loaded all
required assemblies, including others referenced by other referenced
assemblies. In other words, if loading asm A requires loading asm B and asm
B requires asm C, then you wind up needing all 3 assemblies. If one is
loaded in the Load context and it can resolve the transitive closure, then
all 3 end up in the Load context.

Regardless, you could subscribe to the AssemblyResolve event and use that
to
manually locate the Utils.dll for the plugin.


Now, this is interesting! I wasn't aware of this event. I will use it
in my plugin loader mechanism. I could consider that all dependencies
of a plugin are located in the plugin directory itself (which will
also prevent me from clobbering the GAC with various versions of
utils.dll).


If you are using LoadFrom then you absolutely need to become intimately
familiar with that event. Simply putting the other assemblies in the same
directory as where you loaded the other assembly does not guarantee that the
runtime will look there for automatically loading other assemblies.
Jul 21 '05 #4
"David Levine" <no****************@wi.rr.com> wrote in message news:<uy**************@TK2MSFTNGP10.phx.gbl>...
<snip>
Thank you for the detailed information!

Arnaud
MVP - VC
Jul 21 '05 #5

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

1
by: Andy Janssen | last post by:
Hey. I'm working on a program built to support several optional plugins. I'm looking for a way to scan the GAC and find all objects in all assemblies that inherit from a certain interface that each...
0
by: NetWalker | last post by:
I am trying to serialize object using BinaryFormatter like below: //======================== void SomeFunction() { SomeClass anObject; BinaryFormatter bf = new BinaryFormatter();...
2
by: Michel Schilthuizen | last post by:
Hi, I am working on an application that can use functionlity in some sort of plugins. I have implemented this by using Assembly.LoadFrom and MethodInfo.GetMethods. The calling of the plugins...
5
by: Rudolf Ball | last post by:
Dear NG, i want to load a plugin (WinForm) in my Applikation. That works fine. Now I want to globalize that plugin. So I have to load the Satellite Assembly, as well. But how can I load this...
2
by: Matt | last post by:
I'm hoping someone can steer me in the right direction to try to do the following: I am developing an application where we receive files from customers. Right now we receive a variety of...
1
by: Benny Raymond | last post by:
I'm working on adding plugin capability to my application and would like to do it something like this: System.Type myType = System.Type.GetType( "namespace.classname, assembly_name" ); object...
0
by: Oenone | last post by:
I have created a number of "plug-in" DLLs for my ASP.NET application which are dynamically loaded at run-time. This is done by locating the DLL file on disk and loading it using the...
5
by: Arnaud Debaene | last post by:
Hello group. I have an app which can load "plugins" assemblies that are described in the registry (each registry entry gives the full path to the plugin ..dll file). The plugins may be anywhere...
2
by: Luis Arvayo | last post by:
Actually it is: How to define the plugin assemblies path in order to find other assemblies which the plugin depends on. Example: If I have: c:\myapp\application.exe
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...
0
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.