Предоставление типов из встроенного типа взаимодействия другим сборкам

У меня есть библиотека ATL COM, которая определяет перечисление и интерфейс в MIDL, например:

[uuid(65785D49-574A-4B1B-95F1-B9C7F283364A)]
typedef enum Options
{
    Option1,
    Option2
} Options;

[
    object,
    uuid(2E3D1B1A-DF95-434F-836B-73FF1245B608),
    oleautomation,
    nonextensible,
    pointer_default(unique)
]
interface IExample : IUnknown
{
    HRESULT Test([in] Options option, [out, retval] BSTR* str);
};

Затем я создаю управляемую сборку и ссылаюсь на TLB, который создает PIA и встраивает типы (Embed Interop Types = true) в управляемую сборку.

В управляемой сборке я создаю класс, реализующий интерфейс:

public class Example : IExample
{
    public string Test(Options option)
    {
        return option.ToString();
    }
}

Теперь я хотел бы создать третью сборку, которая ссылается на управляемую сборку и создает объект и вызывает ее, но это не позволяет мне, поскольку Options является типом без ссылок (требует, чтобы я включил PIA, созданный из библиотеки типов):

public class Equivalence
{
    public void UseTest()
    {
        Example e = new Example();
        e.Test(Options.Option1);    // recognizes that it requires an ExampleLib.Options parameter, but that type isn't available
    }
}

Используя отражатель, я могу видеть его внутри управляемой сборки, но он не просматривается обозревателем объектов:

namespace ExampleLib
{
    [ComImport, CompilerGenerated, InterfaceType(ComInterfaceType.InterfaceIsIUnknown), Guid("2E3D1B1A-DF95-434F-836B-73FF1245B608"), TypeIdentifier]
    public interface IExample

    [Guid("65785D49-574A-4B1B-95F1-B9C7F283364A"), CompilerGenerated, TypeIdentifier("15a6cf97-c415-4866-bdfb-7da65edb1faa", "ExampleLib.Options")]
    public enum Options
}

Моя управляемая сборка сама по себе является библиотекой, предназначенной для распространения как API, и я хотел бы предоставить это перечисление и интерфейс, чтобы его могли использовать внешние стороны без необходимости доставлять PIA, сгенерированный из библиотеки типов библиотеки ATL COM. Является ли это возможным?


person mford    schedule 03.09.2014    source источник
comment
Не вставляйте типы! Поскольку вы хотите распространять библиотеку ATL вместе со своим API, это все равно не то, что вам нужно. Встраиваются только типы, используемые в сборке, ссылающейся на ваш TLB, поэтому клиенты могут пропустить определенные объекты. Вместо этого вы должны создать PIA из вашего TLB, развернуть его в GAC и ссылаться на него в каждой сборке, которую вы хотите использовать, это типы.   -  person Carsten    schedule 04.09.2014
comment
Нам вообще не нужно (или мы хотим), чтобы внешние клиенты использовали библиотеку ATL, их единственный доступ должен осуществляться через наш управляемый API. Следовательно, единственные типы, которые нам нужно предоставить через этот API, - это те, которые встраиваются. Я медленно прихожу к выводу, что мне нужно распространить PIA, чтобы это работало, но я надеялся, что его можно будет встроить в сборку, чтобы уменьшить зависимости.   -  person mford    schedule 04.09.2014
comment
Единственное, что вы можете встроить в свою сборку, - это типы взаимодействия, которые отличаются от базовых типов COM! Библиотека ATL должна быть развернута и зарегистрирована на клиенте в любом случае, даже если вы встраиваете типы взаимодействия (которые являются просто оболочкой для библиотеки COM). Благодаря этому клиенты могут напрямую обращаться к вашей библиотеке неуправляемых типов. Единственный способ контролировать это - создать и распространить PIA. Зависимости здесь не аргумент - они являются результатом характера вашего решения. Вы не можете уменьшить их, исключив определенные компоненты.   -  person Carsten    schedule 04.09.2014


Ответы (1)


Видимо этого сделать нельзя. Одна из ошибок (CS1748) указала мне на этот пост, в котором говорится, что PIA должна быть связана обеими сборками.

person mford    schedule 06.09.2014