3

Im trying to find out if there is a way to create a local instance of my object that is being referenced from the app domain, reason for this is due to the high amount of chatter I get during all the execution of the method. So instead of having to call the remote object the whole time I'd like to just call a local instance created inside the method.

I've been looking at RemotingServices Marshal and GetObjectData methods but haven't been able to figure out if they will work or not and google hasn't helped either

so the class definition looks as follows

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

And then runtime an instance of the class looks like this.

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

I was hoping to accomplish what I needed along the lines of the following

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);

I get the following error when calling GetRealObject "Attempted to read or write protected memory. This is often an indication that other memory is corrupt."

I still haven't found any way to implement this, anyone perhaps have some suggestions?

Domitius
  • 475
  • 6
  • 17
  • Are you trying to have a local instance of a remote object? If so, you will have two completely separate objects that have no relationship with each other. This means that if the object on the server changes state, your local object will not pickup the changes. You can use an IoC container to retrieve an instance of an object. This is simply a dictionary that uses types as keys and instances as values as they relate to each other. Unity is a popular IoC container. See link: http://msdn.microsoft.com/en-us/library/ff649614.aspx – Scott Nimrod Aug 01 '14 at 10:04
  • Its no problem if the two objects will have no relationship because theres only one part that could change which I'll update afterwards in the remote object. I'll have a look at loC thanks – Domitius Aug 01 '14 at 15:15

1 Answers1

0

Okay. So either install Unity or create your own resource locator (object dictionary).

The following is a resource locator I wrote:

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
    }
}

Then you can do this in your client:

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

ServiceLocator.Instance.Load(serv);

You can retrieve this object like this:

var server = ServiceLocator.Instance[typeof(some_class)] as some_class;
Scott Nimrod
  • 11,206
  • 11
  • 54
  • 118
  • Hi, I've been able to get back to this issue and try your solution. But hopefully I'll be able to do it soon – Domitius Sep 25 '14 at 13:27