\

Školení Návrhové vzory, OOP a UML


 Friday, May 21, 2004
Bezpečná změna verze assembly zveřejněné pro COM

Do konference Emwac VS.NET poslal dotaz pan V. Gazda, jenž se chtěl vyhnout opakované registraci .NET assembly pro COM klienty po změně verze assembly.

Zde je stručný postup vedoucí k eliminaci opakované registrace:

1) Napsal jsem jednoduchou knihovnu s názvem TestLibrary v C#. Rozhraní IType je označeno atributem InterfaceType, kterému je do konstruktoru předána hodnota ComInterfaceType.InterfaceIsDual - rozhraní podporuje brzkou (early) i pozdní (late) vazbu. Rozhraní ITest implementuje třída Test. Z třídy Test je pro Com klienty dostupná pouza metoda Test, protože jsem aplikoval  atribut ClassInterface(ClassInterfaceType.None). Možnost None z enumerace ClassInterfaceType registračním nástrojům signalizuje, že z třídy mají být publikovány pouze metody z  implementovaných rozhraní (tedy určitě ne zděděné metody).

using

System;

using

System.Runtime.InteropServices;

using

System.Reflection;

namespace

RStein

{

[InterfaceType(ComInterfaceType.InterfaceIsDual)]

public interface ITest

{

void TestMethod();

}

[ClassInterface(ClassInterfaceType.None)]

public class Test : ITest

{

public Test()

{

}

public void TestMethod()

{

Console.WriteLine("Hello from COM " + Assembly.GetExecutingAssembly());

}

}

}

2) Vygeneroval jsem silné jméno (strong name), podepsal a zkompiloval verzi  1.0.0.0 assembly.

[assembly: AssemblyVersion("1.0.0.0")]

[assembly: AssemblyKeyFile(@"..\TestLibrary.snk")]

 

3) Assembly jsem zaregistroval pro COM spuštěním  regasm.exe.

RegAsm.exe TestLibrary.dll /tlb:TestLibrary.tlb

4) Napsal jsem primitivního klienta v C++, který přes COM volá metodu TestMethod z rozhraní ITest. Dle očekávání žádný problém.

#include

"stdafx.h"

#include

<wtypes.h>

#import

"mscorlib.tlb"

#import

"TestLibrary.tlb" no_namespace named_guids

int

_tmain(int argc, _TCHAR* argv[])

{

CoInitialize(NULL);

ITest * pTest = NULL;

HRESULT hr = CoCreateInstance(CLSID_Test,

NULL,

CLSCTX_INPROC_SERVER,

IID_ITest,

reinterpret_cast<void**>(&pTest)

);

pTest->TestMethod();

pTest->Release();

CoUninitialize();

}

5) Změnil jsem verzi assembly TestLib.dll na 2.0.0.0, opět jsem kód zkompiloval a umístil do GAC. Verzi 1.0.0.0 jsem z GAC smazal. Po spuštění C++ klienta jsem dostal z metody CoCreateIntance HResult, že nelze nalézt požadovaný soubor.

[assembly: AssemblyVersion("2.0.0.0")]

6) V machine.config jsem instruoval runtime, že nyní mají všichni klienti používat verzi 2.0.0.0 assembly. C++ klient opět typy z assembly TestLib.dll nalezne a žádná opakovaná registrace přes regasm.exe není třeba.

      <dependentAssembly>
        <assemblyIdentity name="TestLibrary" publicKeyToken="12ba27c531641c01" />
        <bindingRedirect oldVersion="1.0.0.0" newVersion="2.0.0.0" />
      </dependentAssembly>



Friday, May 21, 2004 10:14:00 PM (Central Europe Standard Time, UTC+01:00)       
Comments [0]  .NET Framework


Comments are closed.