In .Net framework 2.0, AppDomain.AppendPrivatePath is marked as obsolete.

The deprecation is explained in's break change web site


Title Cache load failures in order to ensure that different app domains do not have different dependency loading success/failure characteristics in domain neutral sharing scenarios.
Area System.Reflection
Affected APIs Deprecating Appdomain.AppendPrivatePath and Appdomain.ClearPrivatePath
Affected Scenarios This change would break code that is dependent on changing the private path of the app-domain after the first assembly has been loaded.
This is actually less common than one would think. ASP.Net though that they relied on this and later learned that they did not.
Description In V1 & Version 1.1, some pathways through the loader recorded a failure to load an assembly and would fail subsequent attempts to load that same assembly into the same AppDomain. However, most pathways through the loader would not cache this binding failure. This lack of caching enables certain scenarios, which some customers are doubtless taking advantage of. This includes a known xaml / JScript Avalon scenario which will break if we start consistently caching our binding failures. That particular scenario (VSV2.0 120644) executes code that contains an AssemblyRef to an assembly that doesn’t exist. Any load failures are trapped. Later, the missing assembly is generated via JScript and subsequent load attempts are expected to succeed.
In V2.0, we would like our new default behavior to break these scenarios. Naturally we would support an opt-in mechanism to force the loader back to the V1 & Version 1.1 behavior via a config file. We would break these scenarios by making the following changes:
- Cache all binding failures per assembly per AppDomain. Subsequent attempts would unconditionally continue to fail. Of course, transient errors like OutOfMemoryException are not considered binding failures and are subject to retry.
- Deprecate AppDomain.AppendPrivatePath and ClearPrivatePath. These APIs allow the application to dynamically change where we look for assemblies to satisfy binding requests. These APIs are subject to race conditions and cannot be reliably used, as I will explain.
Workaround There is no workaround


If you have read my blog about Domain Neutral Assemblies and Caching Binding Failures, you will see that we are toward more on a deterministic binding behavior where we can make sane sharing decision without fearing that our assumption will be broken. Deprecating AppDomain.AppendPrivatePath is a step toward that goal.

The deprecation actually causes quite some confusion. People asks if there is a replacement.

There is no replacement in .Net framework 2.0. There will be no future replacement, as far as I can see.

The only reason I see why AppDomain.AppendPrivatePath can be any useful, is that your application will download some random bits, put them in a sub folder under your application, then use AppDomain.AppendPrivatePath to make them available to the application.

The approach has at least two problems.

First, it makes assembly binding undeterministic. Depending on the assembly binding happens before the download or after, you may see a failure sometimes, or a success the other times. This is exactly the reason why we deprecate AppDomain.AppendPrivatePath in the first place --- WE WANT A DETERMINISTIC BINDING BEHAVIOR.

Second, on a typical Windows machine, applications are installed to C:\Program Files, which by default, only administrators can update. If you start download random bits into the application's sub directory, it practically means your application can only run under administrator account. This is exactly the reason why Windows is so vulnerable, because EVERY APPLICATION REQUIRES ADMINISTRATOR ACCOUNT TO RUN. If you are doing this, please stop, and use your creativity to find alternatives.

Of course, I can't really know all the cases how people use AppDomain.AppendPrivatePath. If you are using it, post your reason here. We can discuss the alternatives.

In any case, if you subscribe AssemblyResolve event, you can probably have your problem solved easily.