在AppDomains上传递自定义对象

时间:2011-12-06 21:32:10

标签: c# serialization appdomain

我编译了一个插件,然后在一个新的AppDomain中创建它的一个实例。然后我想在插件对象中执行一个方法但是会导致 ArgumentException

    "Object of type System.MarshalByRefObject can not be converted to type Data"

下面的代码应该是可编译的,并导致上述例外。要使其工作,您还必须签署程序集(项目 - >属性 - >签名 - >签署程序集 - >新...)

IPlugin.cs:

using System;

namespace Plugin
{
    [Serializable]
    class Data : MarshalByRefObject
    {
        int value;
    }

    interface IPlugin
    {
        void DoStuff(Data data);
    }
}

的Program.cs:

using System;
using System.CodeDom.Compiler;
using System.IO;
using System.Security.Policy;
using System.Security;
using System.Security.Permissions;
using System.Reflection;

namespace Plugin
{
    class Program
    {
        public class Sandbox : MarshalByRefObject
        {
            const string BaseDirectory = "Untrusted";
            const string DomainName = "Sandbox";
            private object instance;

            public static Sandbox Create()
            {
                var setup = new AppDomainSetup()
                {
                    ApplicationBase = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, BaseDirectory),
                    ApplicationName = DomainName,
                    DisallowBindingRedirects = true,
                    DisallowCodeDownload = true,
                    DisallowPublisherPolicy = true
                };

                Evidence ev = new Evidence();
                ev.AddHostEvidence(new Zone(SecurityZone.Internet));

                var permissions = new PermissionSet(PermissionState.None);
                permissions.AddPermission(new ReflectionPermission(ReflectionPermissionFlag.RestrictedMemberAccess));
                permissions.AddPermission(new SecurityPermission(SecurityPermissionFlag.Execution));

                StrongName fullTrustAssembly = typeof(Sandbox).Assembly.Evidence.GetHostEvidence<StrongName>();

                var domain = AppDomain.CreateDomain(DomainName, null, setup, permissions, fullTrustAssembly);

                return (Sandbox)Activator.CreateInstanceFrom(domain, typeof(Sandbox).Assembly.ManifestModule.FullyQualifiedName, typeof(Sandbox).FullName).Unwrap();
            }

            public bool CreateInstance(string assemblyPath, string scriptType)
            {
                new FileIOPermission(FileIOPermissionAccess.Read | FileIOPermissionAccess.PathDiscovery, assemblyPath).Assert();
                var assembly = Assembly.LoadFrom(assemblyPath);
                CodeAccessPermission.RevertAssert();

                Type type = assembly.GetType(scriptType);
                if (type == null)
                    return false;

                instance = Activator.CreateInstance(type);

                return instance != null;
            }

            public object Execute(string method, params object[] parameters)
            {
                Type type = instance.GetType();
                MethodInfo info = type.GetMethod(method);
                return info.Invoke(instance, parameters);
            }
        }

        private static void CompileToFile(string code, string ifaceFile, string output)
        {
            CodeDomProvider provider = CodeDomProvider.CreateProvider("CSharp");

            CompilerParameters p = new CompilerParameters();
            p.GenerateInMemory = false;
            p.GenerateExecutable = false;
            p.OutputAssembly = output;

            provider.CompileAssemblyFromSource(p, code, ifaceFile);
        }

        private static string code = @"
using Plugin;
class MyPlugin : IPlugin
{
    public void DoStuff(Data data)
    {
    }
}
";

        static void Main(string[] args)
        {
            string iface = System.IO.File.ReadAllText(@"C:\Documents and Settings\markus.BLUE\mina dokument\visual studio 2010\Projects\Plugin\Plugin\IPlugin.cs");
            string pluginObjectFile = System.IO.Path.GetTempFileName();
            CompileToFile(code, iface, pluginObjectFile);

            Sandbox s = Sandbox.Create();
            s.CreateInstance(pluginObjectFile, "MyPlugin");

            Data data = new Data();
            s.Execute("DoStuff", data);
        }
    }
}

1 个答案:

答案 0 :(得分:0)

它必须是您沟通双方都知道的类型!