跨AppDomain边界代理匿名对象

| 我要为RazorEngine vNext解决的最受要求的功能之一就是支持将模板程序集加载到单独的“ 0”中,因此我们可以在需要时卸载这些程序集。对功能的要求很高,但具有连锁效应,即对可以注入模板的可能模型类型引入约束。 当前v2.1版本的一个不错的功能之一就是能够使用匿名类型作为模型。我们进行确定模板中的模型类型为匿名类型的工作,并将基本模板设置为
TemplateBase<dynamic>
。运行时绑定程序为我们照顾了模型成员的后期绑定调用。一切都很好。 当我们在单独的ѭ0中引入对运行模板的支持时,我们现在面临一个约束,即模型只能是
[Serializable]
类型(通过继承through4ѭ隐含)。匿名类型不可序列化,并且也是“ 5”。 我的想法是在模板库中以某种方式创建一个代理模型(称为“ 6”),该代理模型将对模型的调用分派(将在调用域中,而不是在模板运行所在的域中)。在本质上: 模板:
<h1>@Model.Name</h1>
呼叫
@Model.Name
会执行以下操作:
Template.Model (ModelProxy) -> GetMember(Name) -> |BOUNDARY| -> Model.Name
是否有人知道或具有尝试将呼叫代理到另一个“ 0”中的匿名(或“ 6”对象)的最佳方法的经验或经验? 重要的是,我并没有试图将匿名对象推过“ 0”边界,这是无法做到的。     
已邀请:
        好。假设您了解反射并创建一个新的
AppDomain
。我知道你知道该怎么做... :) 我创建了两个帮助程序类,这些类允许您传递匿名对象。
ProxyAnonymousObject
ProxyDynamicObject
。您在第一个“ 0”中创建“ 14”,并在另一个“ 0”中使用“ 15”。 (这两个对象都存在于主“ 0”库中)
[Serializable]
public class ProxyAnonymousObject : ISerializable {

    static Dictionary<string, Type> cached = new Dictionary<string, Type>();

    object model;

    public Dictionary<string, object> ModelProperties = new Dictionary<string, object>();

    public ProxyAnonymousObject(object model) { this.model = model; }
    public ProxyAnonymousObject(SerializationInfo info, StreamingContext ctx) {
        try {

            string fieldName = string.Empty;
            object fieldValue = null;

            foreach (var field in info) {
                fieldName = field.Name;
                fieldValue = field.Value;

                if (string.IsNullOrWhiteSpace(fieldName))
                    continue;

                if (fieldValue == null)
                    continue;

                ModelProperties.Add(fieldName, fieldValue);

            }

        } catch (Exception e) {
            var x = e;
        }
    }

    public void GetObjectData(SerializationInfo info, StreamingContext context) {

        foreach (var pi in model.GetType().GetProperties()) {
            info.AddValue(pi.Name, pi.GetValue(model, null), pi.PropertyType);
        }

    }
}

public class ProxyDynamicObject : DynamicObject{
    internal ProxyAnonymousObject Proxy { get; set; }

    public ProxyDynamicObject(ProxyAnonymousObject model) {
        this.Proxy = model;
    }

    public override bool TryGetMember(GetMemberBinder binder, out object result) {
        result = Proxy.ModelProperties[binder.Name];
        return true;
    }
}
为了使它在您的
MarshalByRefObject
继承类中起作用,您只需将目标
dynamic object
设置为等于
new ProxyDynamicObject(model)
。在我编写的示例中,我像这样打电话。
instance = Activator.CreateInstance(type);
var setModel = type.GetMethod(\"SetModel\", BindingFlags.Public | BindingFlags.Instance);
var render = type.GetMethod(\"Render\", BindingFlags.Public | BindingFlags.Instance);

setModel.Invoke(instance, new object[] { new ProxyDynamicObject(model) });
render.Invoke(instance, null);
我已经写了一篇有关它的博客文章http://buildstarted.com/2011/06/28/getting-anonymous-types-to-cross-the-appdomain-boundary/对其进行了更详细的说明。 (尽管这是我不太擅长的事情) 此实现肯定存在问题。它不支持嵌套的匿名类型,并且我确定它会在一般情况下中断。但这绝对是使您走上正确道路的方法。     

要回复问题请先登录注册