创建从 AppDomain 引用的对象的本地实例

Posted

技术标签:

【中文标题】创建从 AppDomain 引用的对象的本地实例【英文标题】:Creating a local instance of an object being referenced from the AppDomain 【发布时间】:2014-07-28 14:29:39 【问题描述】:

我试图找出是否有一种方法可以创建从应用程序域引用的我的对象的本地实例,原因是在方法的所有执行过程中我得到了大量的喋喋不休.因此,不必一直调用远程对象,我只想调用在方法内创建的本地实例。

我一直在研究 RemotingServices Marshal 和 GetObjectData 方法,但无法确定它们是否有效,而且谷歌也没有提供帮助

所以类定义如下所示

[XmlRoot("SI")]
public class SI : MarshalByRefObject, IXmlSerializable

然后运行时该类的实例如下所示。

Name: Service   
Value: System.Runtime.Remoting.Proxies.__TransparentProxy 
Type: SI System.Runtime.Remoting.Proxies.__TransparentProxy

我希望按照以下方式完成我所需要的

var uri =RemotingServices.GetObjectUri(Service);
var serv = RemotingServices.Marshal(Service, uri, typeof(SI)); //Service is the object I described above

SerializationInfo info = new SerializationInfo(typeof(SI), new FormatterConverter());
StreamingContext context = new StreamingContext(StreamingContextStates.All);
serv.GetObjectData(info, context);

var t2 = serv.GetRealObject(context);

调用 GetRealObject 时出现以下错误 “试图读取或写入受保护的内存。这通常表明其他内存已损坏。”

我还没有找到任何方法来实现这个,也许有人有什么建议吗?

【问题讨论】:

您是否尝试拥有远程对象的本地实例?如果是这样,您将拥有两个彼此没有关系的完全独立的对象。这意味着如果服务器上的对象更改状态,您的本地对象将不会获取更改。您可以使用 IoC 容器来检索对象的实例。这只是一个字典,它使用类型作为键,使用实例作为值,因为它们相互关联。 Unity 是一个流行的 IoC 容器。见链接:msdn.microsoft.com/en-us/library/ff649614.aspx 如果两个对象没有关系也没关系,因为只有一个部分可以改变,我稍后会在远程对象中更新。我去看看 loC 谢谢 【参考方案1】:

好的。因此,要么安装 Unity,要么创建自己的资源定位器(对象字典)。

以下是我写的一个资源定位器:

using System;
using System.Collections.Generic;

namespace Bizmonger.Client.Infrastructure

    public class ServiceLocator
    
        #region Members
        Dictionary<Type, object> _dictionary = new Dictionary<Type, object>();
        static ServiceLocator _serviceLocator = null;
        #endregion

        public static ServiceLocator Instance
        
            get
            
                if (_serviceLocator == null)
                
                    _serviceLocator = new ServiceLocator();
                

                return _serviceLocator;
            
        

        public object this[Type key] 
        
            get
            
                if (!_dictionary.ContainsKey(key))
                
                    _dictionary.Add(key, Activator.CreateInstance(key));
                

                return _dictionary[key];
            
            set
            
                _dictionary[key] = value;
            
        

        public bool ContainsKey(Type type)
        
            return _dictionary.ContainsKey(type);
        

        public void Load(object data)
        
            if (data == null)  return; 

            RemoveExisting(data);

            _dictionary.Add(data.GetType(), data);
        

        public void Load(Type type, object data)
        
            if (data == null)  return; 

            RemoveExisting(data);

            _dictionary.Add(type, data);
        

        #region Helpers
        private void RemoveExisting(object data)
        
            bool found = _dictionary.ContainsKey(data.GetType());

            if (found)
            
                _dictionary.Remove(data.GetType());
            
        
        #endregion
    

然后您可以在您的客户端中执行此操作:

var uri =RemotingServices.GetObjectUri(Service);
var serv = RemotingServices.Marshal(Service, uri, typeof(SI)); 

ServiceLocator.Instance.Load(serv);

你可以像这样检索这个对象:

var server = ServiceLocator.Instance[typeof(some_class)] as some_class;

【讨论】:

嗨,我已经能够回到这个问题并尝试您的解决方案。但希望我能很快做到

以上是关于创建从 AppDomain 引用的对象的本地实例的主要内容,如果未能解决你的问题,请参考以下文章

从 AppDomain 创建实例时程序集未解析

如何在新的 AppDomain 中运行从加载到引用的程序集的方法

从 System.Type 在 AppDomain 中创建实例

获取对象的 AppDomain

多个 AppDomain 之间的交互。销毁单例对象的问题

IIS AppDomain 实例化