tôi chỉ làm một thử nghiệm nhanh với List<MBR>
và có vẻ như để làm việc như tôi đã hy vọng:
public class MBR : MarshalByRefObject
{
List<MBR> _list;
public MBR() { _list = new List<MBR> { this }; }
public IList<MBR> Test() { return _list; }
public int X { get; set; }
}
// Later...
var mbr = AppDomainStarter.Start<MBR>(@"C:\Program Files", "test", null, true);
var list = mbr.Test();
list[0].X = 42;
list.Clear();
Debug.WriteLine(string.Format("X={0}, Count={1}", mbr.X, mbr.Test().Count));
Đầu ra là X=42, Count=1
, và gỡ rối cho thấy List<MBR>
chứa một __TransparentProxy
. Vì vậy, rõ ràng, MarshalByRefObject
được sắp xếp thành công bằng cách tham chiếu bên trong một đối tượng khác được so khớp theo giá trị.
Tôi vẫn muốn xem tài liệu hoặc chi tiết kỹ thuật nếu có ai đó có thể tìm thấy.
Đối với bất cứ ai là tò mò, tôi đã viết tiện dụng-dandy sandbox AppDomainStarter này:
/// <summary><see cref="AppDomainStarter.Start"/> starts an AppDomain.</summary>
public static class AppDomainStarter
{
/// <summary>Creates a type in a new sandbox-friendly AppDomain.</summary>
/// <typeparam name="T">A trusted type derived MarshalByRefObject to create
/// in the new AppDomain. The constructor of this type must catch any
/// untrusted exceptions so that no untrusted exception can escape the new
/// AppDomain.</typeparam>
/// <param name="baseFolder">Value to use for AppDomainSetup.ApplicationBase.
/// The AppDomain will be able to use any assemblies in this folder.</param>
/// <param name="appDomainName">A friendly name for the AppDomain. MSDN
/// does not state whether or not the name must be unique.</param>
/// <param name="constructorArgs">Arguments to send to the constructor of T,
/// or null to call the default constructor. Do not send arguments of
/// untrusted types this way.</param>
/// <param name="partialTrust">Whether the new AppDomain should run in
/// partial-trust mode.</param>
/// <returns>A remote proxy to an instance of type T. You can call methods
/// of T and the calls will be marshalled across the AppDomain boundary.</returns>
public static T Start<T>(string baseFolder, string appDomainName,
object[] constructorArgs, bool partialTrust)
where T : MarshalByRefObject
{
// With help from http://msdn.microsoft.com/en-us/magazine/cc163701.aspx
AppDomainSetup setup = new AppDomainSetup();
setup.ApplicationBase = baseFolder;
AppDomain newDomain;
if (partialTrust) {
var permSet = new PermissionSet(PermissionState.None);
permSet.AddPermission(new SecurityPermission(SecurityPermissionFlag.Execution));
permSet.AddPermission(new UIPermission(PermissionState.Unrestricted));
newDomain = AppDomain.CreateDomain(appDomainName, null, setup, permSet);
} else {
newDomain = AppDomain.CreateDomain(appDomainName, null, setup);
}
return (T)Activator.CreateInstanceFrom(newDomain,
typeof(T).Assembly.ManifestModule.FullyQualifiedName,
typeof(T).FullName, false,
0, null, constructorArgs, null, null).Unwrap();
}
}
Vì vậy, nếu MBR là không Serializable, sẽ có một ngoại lệ của một số loại khi .NET Framework cố gắng serialize nó ? Còn về mảng MBR [] thì sao? System.Array là Serializable, và không có nguồn gốc từ MarshalByRefObject. – Qwertie
lại không thể tuần tự hóa: có, ngoại lệ sẽ xảy ra khi chạy. mảng MBR lại: Bạn có cùng vấn đề với Danh sách vì mảng là lớp cấp cao nhất. –
Thử nghiệm cho thấy rằng một MBR không tuần tự hóa bên trong một container tuần tự được truyền qua tham chiếu mà không có ngoại lệ. –