Creation of secondary AppDomains not supported

468 Views Asked by At

The .NET 7 docs provide an example on how to use the MarshalByRefObject class to create class instances in secondary domains. I replicated this example almost identically as follows:

using System;
using System.Reflection;

namespace MarshalByRefObjectExample 
{
    public class Worker : MarshalByRefObject
    {
        public void PrintDomain()
        {
            Console.WriteLine("Object is executing in AppDomain \"{0}\"",
                AppDomain.CurrentDomain.FriendlyName);
        }
    }

    internal class Program
    {
        static void Main(string[] args)
        {      
            // Create an ordinary instance in the current AppDomain
            Worker localWorker = new Worker();
            localWorker.PrintDomain();

            // Create a new AppDomain, an instance of Worker and execute code in there
            AppDomain ad = AppDomain.CreateDomain("New domain");
            Worker remoteWorker = (Worker) ad.CreateInstanceAndUnwrap(
                typeof(Worker).Assembly.FullName,
                "Worker"
            );

            remoteWorker.PrintDomain();       
        }
    }
}

When I run this example, I get an error as follows:

Object is executing in AppDomain "MarshalByRefObjectExample"

Unhandled exception. System.PlatformNotSupportedException: Secondary AppDomains are not supported on this platform.

at System.AppDomain.CreateDomain(String friendlyName)

at MarshalByRefObjectExample.Program.Main(String[] args) in Program.cs:line 24

My project file looks like the following:

<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>net7.0</TargetFramework>
    <RootNamespace>MarshalByRefObjectExample</RootNamespace>
    <Nullable>enable</Nullable>
  </PropertyGroup>
</Project>

What am I doing wrong here?

Edit

After reading some of the comments, I tried redefining my project to use the .NET Framework instead of .NET Core as follows:

<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>net472</TargetFramework>
    <RootNamespace>MarshalByRefObjectExample</RootNamespace>
  </PropertyGroup>

</Project>

I'm getting a different error now:

Unhandled Exception: System.TypeLoadException: Could not load type 'Worker' from assembly 'MarshalByRefObjectExample, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null'.

at System.Reflection.RuntimeAssembly.GetType(RuntimeAssembly assembly, String name, Boolean throwOnError, Boolean ignoreCase, ObjectHandleOnStack type)

at System.Reflection.RuntimeAssembly.GetType(String name, Boolean throwOnError, Boolean ignoreCase)

at System.Activator.CreateInstance(String assemblyString, String typeName, Boolean ignoreCase, BindingFlags bindingAttr, Binder binder, Object[] args, CultureInfo culture, Object[] activationAttributes, Evidence securityInfo, StackCrawlMark& stackMark)

at System.Activator.CreateInstance(String assemblyName, String typeName)

at System.AppDomain.CreateInstance(String assemblyName, String typeName) at System.AppDomain.CreateInstanceAndUnwrap(String assemblyName, String typeName) at System.AppDomain.CreateInstanceAndUnwrap(String assemblyName, String typeName) at MarshalByRefObjectExample.Program.Main(String[] args) in Program.cs:line 25

1

There are 1 best solutions below

3
Hekke On

Quote from https://learn.microsoft.com/en-us/dotnet/core/porting/net-framework-tech-unavailable:

Several technologies available to .NET Framework libraries aren't available for use with .NET 6+, such as app domains, remoting, and code access security (CAS). If your libraries rely on one or more of the technologies listed on this page, consider the alternative approaches mentioned.

For more information on API compatibility, see Breaking changes in .NET.

Application domains Application domains (AppDomains) isolate apps from one another. AppDomains require runtime support and are resource-expensive. Creating more app domains isn't supported, and there are no plans to add this capability in the future. For code isolation, use separate processes or containers as an alternative. To dynamically load assemblies, use the AssemblyLoadContext class.

To make code migration from .NET Framework easier, .NET 6+ exposes some of the AppDomain API surface. Some of the APIs function normally (for example, AppDomain.UnhandledException), some members do nothing (for example, SetCachePath), and some of them throw PlatformNotSupportedException (for example, CreateDomain). Check the types you use against the System.AppDomain reference source in the dotnet/runtime GitHub repository. Make sure to select the branch that matches your implemented version.

More specifically: AppDomains require runtime support and are resource-expensive. Creating more app domains isn't supported, and there are no plans to add this capability in the future.