Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
HomeAnnouncementsFree MagazinesWhite PapersSubmit Content
Discussion GroupsASP.NETWindows FormsLanguages.NET FrameworkVisual Studio.NET
Articles.NET FrameworkASP.NETToolsWindows Forms
.NET DirectoryOpen Source ProjectsUser GroupsWeb Resources
Related Topics
Visual Basic 6SQL ServerMS AccessOther DB ProductsMS Server ProductsMore Topics ...

.NET Forum / .NET Framework / CLR / December 2004

Tip: Looking for answers? Try searching our database.

Appending to CurrentDomain private path using AppDomainSetup

Thread view: 
Enable EMail Alerts  Start New Thread
Thread rating: 
Christoffer - 08 Dec 2004 14:51 GMT
Hello, I'm using the Whidbey beta and I'm having this problem...

I'm developing an application which dynamically loads Assemblies from other
directories. To be sure any dependent assemblies are loaded as well, I add
the Assemby's directory to the PrivatePath of the AppDomain using
AppDomain.CurrentDomain.AppendPrivatePath(pathToAssembly); Now, the new
framework says AppendPrivatePath() is obsolete, and I should use the
AppDomainSetup.PrivateBinPath instead, but I can not see how this can be
done. I can create a AppDomainSetup and set its PrivateBinPath but I can not
add this path to my current AppDomain's private path.

How do I append a path to the AppDomain.CurrentDomain's private path using
AppDomainSetup, avoiding AppDomain.CurrentDomain.AppendPrivatePath?

Cheers,
Chris
rlander@microsoft.com - 15 Dec 2004 00:48 GMT
You can pass an AppDomainSetup object to AppDomain.CreateDomain() at
domain creation time. You cannot do what is being suggested after that
point.

HTH -- rich
rlander [MSFT] - 15 Dec 2004 17:24 GMT
You can only use AppDomainSetup as part of AppDomain creation. You pass
an AppDomainSetup object to AppDomain.CreateDomain. We are moving to a
model in which you set these kind of domain settings at creation and
not later. This avoids a lot of complexity for the way domains behave
and also in our code.

thanks -- rich
David Levine - 16 Dec 2004 01:18 GMT
This will create a huge problem for apps that load plugins, and will break
our existing code. We need the ability to append to the private bin paths
after the appdomain has already been created.

> You can only use AppDomainSetup as part of AppDomain creation. You pass
> an AppDomainSetup object to AppDomain.CreateDomain. We are moving to a
[quoted text clipped - 3 lines]
>
> thanks -- rich
LF - 16 Dec 2004 01:46 GMT
Same for me. We use AppDomain.CurrentDomain.AppendPrivatePath after the
AppDomain has been created. I think it's a bad idea to deprecate it. I
assume many people use it with plugins or in dynamic scenarios.

> This will create a huge problem for apps that load plugins, and will break
> our existing code. We need the ability to append to the private bin paths
[quoted text clipped - 7 lines]
>>
>> thanks -- rich
rlander [MSFT] - 16 Dec 2004 04:39 GMT
We are currently working on better mechanisms for add-ins and dynamic
scenarios. We don't have first class support for these at the moment,
and that's a problem that we are fixing.

You can achieve the same thing by creating a new AppDomain, in which
you can set a new app-base. This is sometimes a great option, and other
times not. Another option is LoadFrom. You must use Load if you are
needing to add private bin paths. Yes?

Any data on scenarios that you would like to see the CLR team enable
w/rt add-ins and dynamic scenarios would be great.

thanks -- rich
David Levine - 16 Dec 2004 07:19 GMT
The problem with Load versus LoadFrom and subscribing to the AssemblyResolve
event is that the assemblies get loaded into different contexts (Load vs.
LoadFrom) and there are some scenarios where the same assembly can get
loaded twice, once into each context. This causes problems when passing
types around amongst these assemblies. The solution was to use Load and
AppendPrivatePath.

Creating separate appdomains for each plugin is something I am looking at
but there are so many other issues surrounding this that I can state as a
certainty that this will involve a major rewrite.

I am all in favor with improving the situation, but without knowing any
details of what is proposed I have no means of evaluating whether the new
"thing" in conjunction with deprecating AppendPrivatePath will break us or
not. All I can say for a certainty is that if all that is done is to
deprecate AppendPrivatePath  then we will definitely break.

> We are currently working on better mechanisms for add-ins and dynamic
> scenarios. We don't have first class support for these at the moment,
[quoted text clipped - 9 lines]
>
> thanks -- rich
rlander [MSFT] - 18 Dec 2004 00:42 GMT
I hear you ... I've got a couple questions for you to help me
understand your scenario:

1. Do the assemblies in these private paths have unique dependent
assemblies or is there some overlap?
2. Why can you not determine all of the private paths at appdomain
creation-time, or are you using the default domain?
3. If you are using the default domain, can you add these private paths
to your config file?

I really want to understand scenarios where you really do find out
about these private paths as you go and cannot know them up front. We
have to ensure that future versions of the Framework accomodate these
scenarios.

I certainly agree that Assembly.Load is the way to go. You avoid issues
that come along with other Loader APIs ...

thanks -- rich
David Levine - 18 Dec 2004 12:48 GMT
Hi Rich,

>I hear you ... I've got a couple questions for you to help me
> understand your scenario:
>
> 1. Do the assemblies in these private paths have unique dependent
> assemblies or is there some overlap?

Both. I plan to have a "common" folder that contains common assemblies with
types to be shared among all the assemblies. I plan to use binding redirects
so that all plugins/components that refer to these common assemblies are all
forced to use the same (current) version. This requires that all common
assemblies be backwardly compatible.

Plugins may have private assemblies that should be kept private (i.e. they
do not share types contained within them). Some plugins may use the same
assembly, (e.g. both reference foo.dll) but possibly of different versions -
local copies of each will be kept.  Private assemblies will not use binding
redirects to force all references to the same version, so there is no
requirement that they be backwardly compatible.

The private assemblies can possibly be handled using the AssemblyResolve
event and using LoadFrom, but this only works so long as types do not need
to get shared. I prefer to have the fusion layer automatically resolve the
references. One possible issue is that as the system evolves and new plugins
get added but old ones do not get modified, an assembly that used to be
private now needs to be shared - in this case the assembly now really ought
to be loaded using Load, not LoadFrom. There wont be binding redirects of
these private assemblies so strict versioning should prevent type
incompatiblities.

> 2. Why can you not determine all of the private paths at appdomain
> creation-time, or are you using the default domain?

Some plugins will use the default appdomain - in fact, most probably will as
it is the easiest and presents the fewest obstacles. But even if it isn't
the default, loading more then one plugin into the same appdomain after it
has been created, default or otherwise, presents the same set of problems -
once the appdomain is created the private paths searched will need to to be
modified.

There is another use case as well: even if all known plugins are determined
and their requirements fed into an appconfig prior to creating the
appdomain, if we don't have the ability to modify the path after that then
this may prevent us from dynamically adding a new plugin without shutting
down the running appdomain. This would create huge problems. One of our uses
for these features is to build a highly available server that loads service
agents dynamically when a master scheduler determines that new work needs to
be done. We cannot have the other agents shutdown while a new agent gets
loaded and initialized.

Also, many people load plugins by examining assemblies in a well known
directory, or pointing the app to a particular directory, and this all
happens after the app is loaded and running. I would expect many of these to
break if that method is removed.

> 3. If you are using the default domain, can you add these private paths
> to your config file?

It's not impossible for static plugins but it does severely constrain what
we have to do to make it work. Here's what I think it would take to make
this work...

I would have to write an engine that runs during installation of the server
that fully analyzes all plugin dependencies and figures out what binding
redirects and codebase hints are needed for all the plugins so they can
locate their dependencies, and then add/merge them into an app config file.
Then figure out how to download a file with a .config extension over a web
service (often this gets blocked) because the files are stored on a central
server and this is a smart client (actually this is easy, but a pain
nonetheless - use a different file extension, but then it becomes a custom
file), then figure out how to tell the launcher which app config to use - we
want this to be a generic launcher, not one that is product specific. If a
plugin is added to the default list on the server then the installation
piece has to run again to add in the new dependencies, then all running
clients need to be shutdown and restarted to use the new plugin, instead of
just updating the files in place.

It does not handle adding new plugins at runtime without shutting down a
running application. It also does not handle the case where a user may want
to add a plugin locally on the client without adding it to the central
server's repository.

Perhaps there are simpler ways of handling this.

I would prefer to not have to write this as a collection of entirely
separate executables - that's what we did in the past and it was very
constraining.

> I really want to understand scenarios where you really do find out
> about these private paths as you go and cannot know them up front. We
> have to ensure that future versions of the Framework accomodate these
> scenarios.

Believe me, I appreciate the chance to provide input - I think everyone up
here appreciates it. Unfortunately, I don't have all the use cases worked
out because this is still a work in progress.

Here are some requirements:
All assemblies shall be signed - this forces strict binding.
This is a smart client that is centrally distributed on a server. The
product is initially installed on the server and clients distributed by a
click-once type installation (not using click-once, but similar).
Each plugin may have a set of private assemblies.
Each plugin may bind to common assemblies for shareable types. Common
assemblies must be backwardly compatible.
Plugins can bind to the same private assembly, the same version (located in
one or more directories), for non-shareable types.
Plugins can bind to the same private assembly, but of different versions
(located in different directories), for non-shareable types.
Private assemblies do not need to be backwardly compatible (but ought to be
if possible). If not, then it cannot be shared.
Each plugin can choose to or be forced to load in a separate appdomain. The
default is to load in the default appdomain (or the appdomain of the smart
client frame).  e.g. if it must run with reduced security settings.
A set of plugins ships with the product and is installed on the server -
this constitutes the base set of plugins.
The application is field extensible - plugins can be added after initial
installation.
Plugins can be added centrally so that it is common to all clients.
Plugins can be added locally so that it is private to a single client.
Plugins can bind to other plugins.
The plugin assemblies must be capable of being updated while the client is
running; the new bits wont take effect until the plugin is restarted.
Plugins may be written by third parties. This implies that they may be built
against different versions of common assemblies then what is actually
installed in the field. It also requires that a means of installing the
plugin to the client or server be provided.
All plugins are to be xcopy deployable - nothing needs to be installed into
the GAC.

I'm sure others can be added to this list...it's a start.

> I certainly agree that Assembly.Load is the way to go. You avoid issues
> that come along with other Loader APIs ...

Agreed.

Thanks for listening; regards,
Dave
LF - 16 Dec 2004 12:44 GMT
Yes, I'm using Assembly.Load. I'm trying to stick to one Loading context
only. When I was using LoadFrom and Load I ran into problems. With
Assembly.Load used consistently I don't have any problems (Not related to
casting types).

> We are currently working on better mechanisms for add-ins and dynamic
> scenarios. We don't have first class support for these at the moment,
[quoted text clipped - 9 lines]
>
> thanks -- rich

Rate this thread:







Free Magazines

Get these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...

Oracle MagazineNetwork ComputingComputer WorldBio-IT WorldeWeekInformation WeekInfosecurity
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2008 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.