AppDomain.DynamicDirectory Property

Definition

Gets the directory that the assembly resolver uses to probe for dynamically created assemblies.

C#
public string? DynamicDirectory { get; }
C#
public string DynamicDirectory { get; }

Property Value

The directory that the assembly resolver uses to probe for dynamically created assemblies.

Implements

Exceptions

The operation is attempted on an unloaded application domain.

Examples

The following example creates an application domain with a directory for dynamic assemblies, emits a dynamic assembly and stores it in the dynamic directory, and then loads the assembly into the new application domain and uses it.

The example creates an AppDomainSetup object and sets its ApplicationName property to "Example" and its DynamicBase property to "C:\DynamicAssemblyDir". The example then displays the DynamicBase property, to show that the hash code of the application name has been appended as a subdirectory of the path that was originally assigned.

Note

The base directory in this example is intended to be outside the probing path for the example application. Be sure to compile the example in a different location. Delete the base directory and all its subdirectories each time you run the example.

The example creates a new application domain, using the AppDomainSetup object. The example uses the DynamicDirectory property to retrieve the name of the directory, so it can create the directory. (The example could just as easily create the directory beforehand by concatenating the original path, the hash code of the application name, and the application name.)

The example has a GenerateDynamicAssembly method that emits an assembly named DynamicHelloWorld.dll and stores it in the new application domain's dynamic directory. The dynamic assembly contains one type, HelloWorld, that has a static method (Shared method in Visual Basic) named HelloFromAD. Calling this method displays the name of the application domain.

The Example class derives from MarshalByRefObject, so the example can create an instance of the class in the new application domain and call its Test method. The Test method loads the dynamic assembly by its display name and calls the static HelloFromAD method.

You can show that the dynamic directory is searched after the normal probing paths by writing code for an assembly named DynamicHelloWorld.dll and compiling it in the same directory as this example. The assembly must have a class named HelloWorld with a static method named HelloFromAD. This method does not have to have the same functionality as the one in the example; it can simply display a string to the console. The assembly must also have an AssemblyVersionAttribute attribute that sets its version to 1.0.0.0. When you run the example, the assembly you compiled in the current directory is found before the dynamic directory is searched.

C#
using System;
using System.Reflection;
using System.Reflection.Emit;

public class AddDynamicBaseSnippet : MarshalByRefObject
{
   static void Main()
   {
      // Prepare to create a new application domain.
      AppDomainSetup setup = new AppDomainSetup();

      // Set the application name before setting the dynamic base.
      setup.ApplicationName = "Example";

      // Set the location of the base directory where assembly resolution
      // probes for dynamic assemblies. Note that the hash code of the
      // application name is concatenated to the base directory name you
      // supply.
      setup.DynamicBase = "C:\\DynamicAssemblyDir";
      Console.WriteLine("DynamicBase is set to '{0}'.", setup.DynamicBase);

      AppDomain ad = AppDomain.CreateDomain("MyDomain", null, setup);

      // The dynamic directory name is the dynamic base concatenated with
      // the application name: <DynamicBase>\<hash code>\<ApplicationName>
      string dynamicDir = ad.DynamicDirectory;
      Console.WriteLine("Dynamic directory is '{0}'.", dynamicDir);

      // The AssemblyBuilder won't create this directory automatically.
      if (!System.IO.Directory.Exists(dynamicDir))
      {
         Console.WriteLine("Creating the dynamic directory.");
         System.IO.Directory.CreateDirectory(dynamicDir);
      }

      // Generate a dynamic assembly and store it in the dynamic
      // directory.
      GenerateDynamicAssembly(dynamicDir);

      // Create an instance of the Example class in the application domain,
      // and call its Test method to load the dynamic assembly and use it.
      AddDynamicBaseSnippet ex = (AddDynamicBaseSnippet) ad.CreateInstanceAndUnwrap(
         typeof(AddDynamicBaseSnippet).Assembly.FullName, "Example");
      ex.Test();
   }

   public void Test()
   {
      Assembly dynAssem = Assembly.Load(
         "DynamicHelloWorld, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null");

      Type myType = dynAssem.GetType("HelloWorld");
      myType.InvokeMember("HelloFromAD", BindingFlags.Public |
         BindingFlags.Static | BindingFlags.InvokeMethod,
         Type.DefaultBinder, null, null);
   }

   private static void GenerateDynamicAssembly(string location)
   {
      // Define the dynamic assembly and the module. There is only one
      // module in this assembly. Note that the call to DefineDynamicAssembly
      // specifies the location where the assembly will be saved. The
      // assembly version is 1.0.0.0.
      //
      AssemblyName asmName = new AssemblyName("DynamicHelloWorld");
      asmName.Version = new Version("1.0.0.0");

      AssemblyBuilder ab =
         AppDomain.CurrentDomain.DefineDynamicAssembly(
            asmName, AssemblyBuilderAccess.Save, location);

      String moduleName = asmName.Name + ".exe";
      ModuleBuilder mb = ab.DefineDynamicModule(asmName.Name, moduleName);

      // Define the "HelloWorld" type, with one static method.
      TypeBuilder tb = mb.DefineType("HelloWorld", TypeAttributes.Public);
      MethodBuilder hello = tb.DefineMethod("HelloFromAD",
         MethodAttributes.Public | MethodAttributes.Static, null, null);

      // The method displays a message that contains the name of the application
      // domain where the method is executed.
      ILGenerator il = hello.GetILGenerator();
      il.Emit(OpCodes.Ldstr, "Hello from '{0}'!");
      il.Emit(OpCodes.Call, typeof(AppDomain).GetProperty("CurrentDomain").GetGetMethod());
      il.Emit(OpCodes.Call, typeof(AppDomain).GetProperty("FriendlyName").GetGetMethod());
      il.Emit(OpCodes.Call, typeof(Console).GetMethod("WriteLine",
                             new Type[] { typeof(String), typeof(String) }));
      il.Emit(OpCodes.Ret);

      // Complete the HelloWorld type and save the assembly. The assembly
      // is placed in the location specified by DefineDynamicAssembly.
      Type myType = tb.CreateType();
      ab.Save(moduleName);
   }
}

/* This example produces output similar to the following:

DynamicBase is set to 'C:\DynamicAssemblyDir\5e4a7545'.
Dynamic directory is 'C:\DynamicAssemblyDir\5e4a7545\Example'.
Creating the dynamic directory.
Hello from 'MyDomain'!
 */

Remarks

To set the dynamic directory, assign a base directory path to the AppDomainSetup.DynamicBase property of the AppDomainSetup object that will be used to create the new application domain. The base directory path you assign to the property is modified by the addition of a subdirectory whose simple name is the hash code of the string you assign to the AppDomainSetup.ApplicationName property, so the format of the base directory is original path\hash code. The dynamic directory is a subdirectory of this base directory. Its simple name is the value of the AppDomainSetup.ApplicationName property, so its format is original path\hash code\application name.

Applies to

Product Versions
.NET Core 2.0, Core 2.1, Core 2.2, Core 3.0, Core 3.1, 5, 6, 7, 8, 9
.NET Framework 1.1, 2.0, 3.0, 3.5, 4.0, 4.5, 4.5.1, 4.5.2, 4.6, 4.6.1, 4.6.2, 4.7, 4.7.1, 4.7.2, 4.8, 4.8.1
.NET Standard 2.0, 2.1