Почему я не должен использовать AutoDual? - PullRequest
9 голосов
/ 26 апреля 2010

До сих пор я всегда украшал свои классы .NET, которые я хочу использовать из VB6, атрибутом [AutoDual]. Задача состояла в том, чтобы получить Intellisense для объектов .NET в среде VB6. Однако на днях я набрал в Google AutoDual, и первый ответ - «Не использовать AutoDual».

Я искал внятного объяснения, почему я не должен его использовать, но не смог его найти.

Может кто-нибудь здесь это объяснить?

Ответы [ 2 ]

11 голосов
/ 29 апреля 2010

Я нашел надежный способ предоставить Intellisense для объектов .NET в VB6, не нарушая при этом интерфейс. Ключ должен пометить каждый открытый метод / свойство в интерфейсе DispatchID. Затем класс должен наследовать от этого интерфейса - как описано ниже.

[Guid("BE5E0B60-F855-478E-9BE2-AA9FD945F177")]
[InterfaceType(ComInterfaceType.InterfaceIsIDispatch)]
public interface ICriteria
{
    [DispId(1)]
    int ID { get; set; }
    [DispId(2)]
    string RateCardName { get; set; }
    [DispId(3)]
    string ElectionType { get; set; }
}


[Guid("3023F3F0-204C-411F-86CB-E6730B5F186B")]    
[ClassInterface(ClassInterfaceType.None)]
[ProgId("MyNameSpace.Criteria")]
public class Criteria : ICriteria
{
    public int ID { get; set; }
    public string RateCardName { get; set; }
    public string ElectionType { get; set; }
}

То, что дает вам идентификатор отправки, - это возможность перемещаться по предметам в классе, плюс теперь вы можете добавлять новые вещи в класс и не нарушать двоичную совместимость.

9 голосов
/ 26 апреля 2010

Я думаю, что это подводит итог:

Типы, использующие двойной интерфейс, позволяют клиенты связываются с конкретным макет интерфейса. Любые изменения в будущая версия к макету тип или любые базовые типы сломают COM клиенты, которые привязываются к интерфейсу. От по умолчанию, если Атрибут ClassInterfaceAttribute не указано, отправка только используется интерфейс.

http://msdn.microsoft.com/en-us/library/ms182205.aspx

Это увеличивает вероятность того, что изменение чего-либо в этом классе с помощью атрибута auto dual нарушит чужой код при изменении класса. Если он дает потребителю возможность сделать что-то, что вполне может вызвать у него проблемы в будущем.

Следующая опция - ClassInterfaceType.AutoDual. Это быстрый и грязный способ получения поддержки раннего связывания (и отображения методов в VB6 IntelliSense). Но также легко нарушить совместимость, изменив порядок методов или добавив новые перегрузки. Избегайте использования AutoDual.

http://www.dotnetinterop.com/faq/?q=ClassInterface

Я наконец-то нашел ссылку, которая рассказывает о том, что происходит с AutoDual и как он работает:

http://social.msdn.microsoft.com/Forums/en-US/csharpgeneral/thread/7fa723e4-f884-41dd-9405-1f68afc72597

Предупреждение против AutoDual не является факт, что двойные интерфейсы это плохо, но тот факт, что он автоматически генерирует COM интерфейс для вас. Это плохо. Каждый раз, когда интерфейс COM должен быть Восстановленный вы получите новый GUID и потенциально новые участники. Если GUID меняется, то вы получаете совершенно новый интерфейс / класс, насколько COM обеспокоен. Для раннего связывания вы бы приходится перестраивать клиентов каждый раз интерфейс был восстановлен. Предпочтительный подход заключается в определении Интерфейс класса COM явно с GUID. Тогда все раннее связывание клиенты могут использовать определенный интерфейс и не волнуйтесь, что это меняется их в процессе разработки. Поэтому рекомендуемый вариант - не сообщать CLR, чтобы не генерировать его автоматически вы. Вы все еще можете реализовать двойной хотя интерфейс, если вам это нужно.

...