Skip to content

Proxy Generation

Cy Scott edited this page May 20, 2019 · 2 revisions

AppDomainAlternative uses a proxy generator to support remoting a class instance across the process barrier similar to AppDomains using classes that inherit from MarshalByRefObject to support remoting across the AppDomain barrier. Remoting was an important feature for AppDomains and is no longer supported in .Net Core. Which means classes that inherit from MarshalByRefObject can no longer be used for remoting from one domain to another. Classes that inherit from MarshalByRefObject work by creating a proxy instance on a remote domain and all calls to that proxy instance are serialized and passed to the original domain for execution. Here is an example class that can be proxied across the domain barrier:

public class ChatRoom : MarshalByRefObject
{
	public void SendMessage(string message)
	{
		Console.WriteLine(message);
	}
}

AppDomainAlternative takes a similar approach to remoting across the process barrier by using the default proxy factory to generate proxy instances. However, there is no need to inherit from a special class. Here is an example class that can be proxied across the process barrier:

public class ChatRoom
{
	public virtual void SendMessage(string message)
	{
		Console.WriteLine(message);
	}
}

The difference is the methods and properties need to be marked as virtual. This allows AppDomainAlternative to create a proxy instance of the class by overriding those methods and properties. The override of those methods and properties handle the remoting responsibilities, include exceptions thrown by the remote call.

Custom Proxy Generators

A proxy generator must implement the IGenerateProxies interface to replace the default one. After creating the proxy generator, a resolver needs to be added to the DomainConfiguration so a child process will know which proxy generator to use for IPC with the parent. This setting should be modified like the example below:

DomainConfiguration.Resolver = name =>
{
	var match = Regex.Match(name, @"^MyProxyGenerator@(?<MAJOR>\d+)\.(?<MINOR>\d+)\.(?<PATCH>\d+)$");

	if (!match.Success ||
		!int.TryParse(match.Groups["MAJOR"].Value, out var major) ||
		!int.TryParse(match.Groups["MINOR"].Value, out var minor) ||
		!int.TryParse(match.Groups["PATCH"].Value, out var patch))
	{
		return null;//if the proxy generator is not found then the resolver should return null
	}

	if (major == 1)
	{
		return new MyProxyGenerator();
	}

	return null;//if the proxy generator is not found then the resolver should return null
};

Clone this wiki locally