как создать COM-синглтон?
От: Аноним  
Дата: 07.06.11 07:32
Оценка:
Нужно сделать так, чтобы один COM-объект создавался при старте моего сервера и использовался всеми запросами к этому коклассу. Это возможно? (COM-сервер и клиент находятся в одном процессе)
Как альтернатива, можно чтобы создалось несколько COM-объектов, но мне нужно быть уверенным, что они все будут созданы в одном app domain.
Есть идеи?
Re: как создать COM-синглтон?
От: HowardLovekraft  
Дата: 07.06.11 08:15
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Нужно сделать так, чтобы один COM-объект создавался при старте моего сервера и использовался всеми запросами к этому коклассу. Это возможно?

Напишите singleton-обертку для COM-объекта.
Re[2]: как создать COM-синглтон?
От: Аноним  
Дата: 07.06.11 08:19
Оценка:
Здравствуйте, HowardLovekraft, Вы писали:

HL>Напишите singleton-обертку для COM-объекта.


Что ты имеешь в виду?
Re[3]: как создать COM-синглтон?
От: HowardLovekraft  
Дата: 07.06.11 08:37
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Что ты имеешь в виду?

    public static class ComSingleton
    {
        private static readonly Type type;
        private static readonly Object instance;

        static ComSingleton()
        {
            type = Type.GetTypeFromProgID("MyComLibrary.MyComServer", true);
            instance = Activator.CreateInstance(type);
        }

        public static Object Instance
        {
            get { return instance; }
        }

        public static Type Type
        {
            get { return type; }
        }
    }

Смысл в том, чтобы заморачиваться с синглтон-поведением не в COM, а в шарпе.
Re[4]: как создать COM-синглтон?
От: bugmenot  
Дата: 07.06.11 08:39
Оценка:
Здравствуйте, HowardLovekraft, Вы писали:

HL>Смысл в том, чтобы заморачиваться с синглтон-поведением не в COM, а в шарпе.


Это не то. Если вызывать его в in-proc mode, то будет по одному экземпляру объекта на каждый app domain, насколько я понимаю.
Re: как создать COM-синглтон?
От: okman Беларусь https://searchinform.ru/
Дата: 07.06.11 08:43
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Нужно сделать так, чтобы один COM-объект создавался при старте моего сервера и использовался всеми запросами к этому коклассу. Это возможно? (COM-сервер и клиент находятся в одном процессе)

А>Как альтернатива, можно чтобы создалось несколько COM-объектов, но мне нужно быть уверенным, что они все будут созданы в одном app domain.
А>Есть идеи?

Почему нельзя сделать COM-синглетон в exe (LocalServer), а на клиентах
использовать прокси для доступа к нему ?
Re[2]: как создать COM-синглтон?
От: Аноним  
Дата: 07.06.11 08:44
Оценка:
Здравствуйте, okman, Вы писали:

O>Почему нельзя сделать COM-синглетон в exe (LocalServer), а на клиентах

O>использовать прокси для доступа к нему ?

Таковы условия задачи. Добавочный процесс создавать нельзя.
Re[5]: как создать COM-синглтон?
От: HowardLovekraft  
Дата: 07.06.11 08:50
Оценка:
Здравствуйте, bugmenot, Вы писали:

B>будет по одному экземпляру объекта на каждый app domain, насколько я понимаю.

Это не рабочий код, а идея.
Если предполагается использование нескольких доменов, то можно создать домен с заранее определенным именем, в нем создать экземпляр COM-объекта, а из обертки получать бы прокси к этому экземпляру.
Re[3]: как создать COM-синглтон?
От: okman Беларусь https://searchinform.ru/
Дата: 07.06.11 08:50
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Здравствуйте, okman, Вы писали:


O>>Почему нельзя сделать COM-синглетон в exe (LocalServer), а на клиентах

O>>использовать прокси для доступа к нему ?

А>Таковы условия задачи. Добавочный процесс создавать нельзя.


Значит, нужно COM-сервер должен использовать разделяемые между процессами данные,
чтобы выглядеть логически эквивалентно синглетону.
Например, через файлы, отображаемые в память или секции данных, помеченные
соответствующим атрибутом.
Не знаю, как это делается в .NET, но в Win32 — довольно просто.
Re[6]: как создать COM-синглтон?
От: bugmenot  
Дата: 07.06.11 08:52
Оценка:
Здравствуйте, HowardLovekraft, Вы писали:

HL>Это не рабочий код, а идея.


По моему, она неработоспособная

HL>Если предполагается использование нескольких доменов


Предполагается, в вопросе написано же

HL>а из обертки получать бы прокси к этому экземпляру.


Как?
Re[7]: как создать COM-синглтон?
От: HowardLovekraft  
Дата: 07.06.11 10:08
Оценка: 2 (1)
Здравствуйте, bugmenot, Вы писали:

B>Как?

Примерно вот так:

1) хост:
  Скрытый текст
    public class SingletonHost<T> : MarshalByRefObject
        where T : MarshalByRefObject, new()
    {
        private static readonly T instance;

        static SingletonHost()
        {
            instance = (T)Activator.CreateInstance(typeof(T));
        }

        public T Instance
        {
            get { return instance; }
        }
    }


2) клиент:
  Скрытый текст
    public class SingletonClient<T> : IDisposable
        where T : MarshalByRefObject
    {
        private const String Mutex_Name = "CrossDomainSingleton";
        private const String Host_Domain_Name = "SingletonDomain";

        private readonly Mutex mutex;

        private IEnumerable<AppDomain> GetAppDomains()
        {
            IntPtr enumHandle;

            var host = new mscoree.CorRuntimeHost();
            host.EnumDomains(out enumHandle);
            try
            {
                Object domain = null;

                do
                {
                    host.NextDomain(enumHandle, out domain);
                    if (domain != null)
                        yield return (AppDomain)domain;
                }
                while (domain != null);
            }
            finally
            {
                host.CloseEnum(enumHandle);
                Marshal.ReleaseComObject(host);
            }
        } 

        public SingletonClient()
        {
            mutex = new Mutex(false, Mutex_Name);
        }

        public T Instance
        {
            get
            {
                mutex.WaitOne();
                try
                {
                    var hostDomain = GetAppDomains().SingleOrDefault(d => d.FriendlyName == Host_Domain_Name);

                    if (hostDomain == null)
                        hostDomain = AppDomain.CreateDomain(Host_Domain_Name);

                    var host = (SingletonHost<T>)hostDomain.CreateInstanceAndUnwrap(Assembly.GetExecutingAssembly().FullName,
                        typeof(SingletonHost<T>).FullName);

                    return host.Instance;
                }
                finally
                {
                    mutex.ReleaseMutex();
                }
            }
        }

        #region IDisposable Members

        public void Dispose()
        {
            Dispose(true);
            GC.SuppressFinalize(this);
        }

        protected virtual void Dispose(Boolean disposing)
        {
            if (disposed)
                return;

            if (disposing)
            {
                if (mutex != null)
                    mutex.Dispose();
            }

            disposed = true;
        }

        private Boolean disposed;

        #endregion
    }


Ну и всю работу с COM-объектом заворачиваете в какого-нибудь наследника MBR.
Выдрано из тестового проекта, поэтому доработать напильником.

Рекомендую еще погуглить на тему cross-domain singleton — это не единственный вариант реализации.
Re[8]: как создать COM-синглтон?
От: bugmenot  
Дата: 07.06.11 10:37
Оценка:
Здравствуйте, HowardLovekraft, Вы писали:

HL>Ну и всю работу с COM-объектом заворачиваете в какого-нибудь наследника MBR.

HL>Выдрано из тестового проекта, поэтому доработать напильником.

HL>Рекомендую еще погуглить на тему cross-domain singleton — это не единственный вариант реализации.


А вот этот new mscoree.CorRuntimeHost(); откуда берется?
Re[9]: как создать COM-синглтон?
От: HowardLovekraft  
Дата: 07.06.11 11:05
Оценка:
Здравствуйте, bugmenot, Вы писали:

B>А вот этот new mscoree.CorRuntimeHost(); откуда берется?

Нужно добавить ссылку на mscoree.tlb.
Re[10]: как создать COM-синглтон?
От: bugmenot  
Дата: 07.06.11 11:16
Оценка:
Здравствуйте, HowardLovekraft, Вы писали:

HL>Нужно добавить ссылку на mscoree.tlb.


Ага, то есть через COM. А это насколько надежно работает? Никаких проблем с разными версиями дотнета или еще чем?
Re: как создать COM-синглтон?
От: TK Лес кывт.рф
Дата: 07.06.11 13:11
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Нужно сделать так, чтобы один COM-объект создавался при старте моего сервера и использовался всеми запросами к этому коклассу. Это возможно? (COM-сервер и клиент находятся в одном процессе)

А>Как альтернатива, можно чтобы создалось несколько COM-объектов, но мне нужно быть уверенным, что они все будут созданы в одном app domain.
А>Есть идеи?

Смотрите на ExtensibleClassFactory
Если у Вас нет паранойи, то это еще не значит, что они за Вами не следят.
Re: как создать COM-синглтон?
От: scale_tone Норвегия https://scale-tone.github.io/
Дата: 07.06.11 15:10
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Есть идеи?


DECLARE_CLASSFACTORY_SINGLETON обычно используется для внепроцессных объектов, но работает и для внутрипроцессных. Вставьте этот макрос в объявление класса — и будет Вам счастье.
Но это, конечно, если COM-объект на C++ написан.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.