https://github.com/chaoses-ib/marshalbyrefproxy
A .NET library for marshalling any object by reference that do not require the object to inherit from MarshalByRefObject.
https://github.com/chaoses-ib/marshalbyrefproxy
appdomain dotnet-remoting marshal marshalling
Last synced: about 1 year ago
JSON representation
A .NET library for marshalling any object by reference that do not require the object to inherit from MarshalByRefObject.
- Host: GitHub
- URL: https://github.com/chaoses-ib/marshalbyrefproxy
- Owner: Chaoses-Ib
- License: apache-2.0
- Created: 2023-01-19T23:32:39.000Z (over 3 years ago)
- Default Branch: main
- Last Pushed: 2023-01-25T06:22:33.000Z (over 3 years ago)
- Last Synced: 2025-04-27T00:18:42.647Z (about 1 year ago)
- Topics: appdomain, dotnet-remoting, marshal, marshalling
- Language: C#
- Homepage:
- Size: 116 KB
- Stars: 5
- Watchers: 2
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE.txt
Awesome Lists containing this project
README
# MarshalByRefProxy
[](https://www.nuget.org/packages/MarshalByRefProxy)
A .NET library for marshalling any object by reference that do not require the object to inherit from [MarshalByRefObject](https://learn.microsoft.com/en-us/dotnet/api/system.marshalbyrefobject).
This project is based on [ImpromptuInterface](https://github.com/ekonbenefits/impromptu-interface).
## Basic usage
```csharp
using MarshalByRefAsProxy;
public interface IProxyInterface
{
string GetCurrentAppDomainName();
}
// UnmarshallableClass is not required to inherit from IProxyInterface.
// Here we inherit from IProxyInterface just to be able to call CreateInstance() for comparison.
class UnmarshallableClass : IProxyInterface
{
public string GetCurrentAppDomainName() => AppDomain.CurrentDomain.FriendlyName;
}
class ClassFactory : MarshalByRefObject
{
public IProxyInterface CreateInstance() => new UnmarshallableClass();
public IProxyInterface CreateMarshalByRefInstance() => new UnmarshallableClass().MarshalByRefAs();
}
[Test]
public void TestCrossAppDomain()
{
// Create an application domain named TestDomain
AppDomain domain = AppDomain.CreateDomain("TestDomain");
ClassFactory factory = (ClassFactory)domain.CreateInstanceFromAndUnwrap(typeof(ClassFactory).Assembly.Location, typeof(ClassFactory).FullName);
// Try to marshal an unmarshallable object, which throws a SerializationException
Assert.Throws(() => factory.CreateInstance().GetCurrentAppDomainName());
// Try to marshal an unmarshallable object via MarshalByRefProxy, which works fine
Assert.AreEqual("TestDomain", factory.CreateMarshalByRefInstance().GetCurrentAppDomainName());
}
```
## Task
```csharp
class TaskTest : MarshalByRefObject
{
// Cannot be an async method
// The return type cannot be IAwaitable
public IAwaitable GetCurrentAppDomainNameAsync()
{
Task.Delay(1000).Wait();
// IAwaitable is defined by MarshalByRefProxy
return Task.Run(() => AppDomain.CurrentDomain.FriendlyName).MarshalByRefAs();
}
}
[Test]
public async Task TestTask()
{
AppDomain domain = AppDomain.CreateDomain("TestDomain");
TaskTest test = (TaskTest)domain.CreateInstanceFromAndUnwrap(typeof(TaskTest).Assembly.Location, typeof(TaskTest).FullName);
string name = (string)await test.GetCurrentAppDomainNameAsync();
Assert.AreEqual("TestDomain", name);
}
```
Why can we await `IAwaitable`? Because C# can await any [awaitable expressions](https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/language-specification/expressions#11882-awaitable-expressions), which is exactly what `IAwaitable` stands for.
## Permissions (.NET Framework only)
Assert unrestricted permissions:
```csharp
using System.Security;
using System.Security.Permissions;
new UnmarshallableClass().MarshalByRefAs(new PermissionSet(PermissionState.Unrestricted));
```
## Todos
- [ ] `IAwaitable`
- [ ] MarshalByRefWrapper Code Generators
- [ ] MarshalByRefObject Code Generators