2010-04-26 12 views
7

Bis jetzt habe ich immer meine .NET-Klassen, die ich von VB6 mit dem [AutoDual] Attribut verwenden möchte, dekoriert. Der Punkt war, Intellisense für .NET-Objekte in der VB6-Umgebung zu gewinnen. Aber neulich habe ich AutoDual gegoogelt und die erste Antwort ist 'Do not Use AutoDual'.Warum sollte ich AutoDual nicht verwenden?

Ich habe nach einer kohärenten Erklärung gesucht, warum ich es nicht verwenden sollte, aber ich konnte es nicht finden.

Kann jemand hier erklären?

Antwort

8

Ich denke, das bringt es auf:

Typen, die eine duale Schnittstelle erlauben Clients verwenden, um ein bestimmtes Schnittstelle Layout zu binden. Alle Änderungen in einer zukünftigen Version an das Layout des Typs oder eines Basistyps werden COM Clients, die an die Schnittstelle binden, unterbrechen. Nach Standard, wenn das ClassInterfaceAttribute-Attribut nicht angegeben ist, wird eine Nur-Senden-Schnittstelle verwendet.

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

Es erhöht die Möglichkeit, dass mit dem Auto Dual-Attribute in dieser Klasse etwas zu ändern bricht jemand anderen Code, wenn die Klasse geändert wird. Wenn der Verbraucher die Möglichkeit hat, etwas zu tun, das ihnen in Zukunft möglicherweise Probleme bereiten wird.

Die nächste Option ist ClassInterfaceType.AutoDual. Dies ist der schnelle und schmutzige Weg, um frühe Bindungsunterstützung zu erhalten (und die Methoden in VB6 IntelliSense erscheinen zu lassen). Es ist aber auch einfach, die Kompatibilität zu unterbrechen, indem Sie die Reihenfolge der Methoden ändern oder neue Überladungen hinzufügen. Vermeiden Sie die Verwendung von AutoDual.

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

fand ich endlich den Link, der darüber spricht, was mit AutoDual los ist und wie es funktioniert:

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

Die Warnung vor AutoDual ist nicht die Tatsache, dass Dual-Schnittstellen ist aber die Tatsache, dass es automatisch die COM-Schnittstelle für Sie generiert. Das ist schlecht. Jedes Mal, wenn die COM-Schnittstelle regeneriert werden muss, erhalten Sie eine neue GUID und potenziell neue Mitglieder. Wenn sich die GUID ändert, erhalten Sie eine brandneue Schnittstelle/Klasse, soweit COM betroffen ist. Für frühe Bindung müssten Sie die Clients jedes Mal neu erstellen die Schnittstelle wurde neu generiert. Der bevorzugte Ansatz besteht darin, die COM-Klassenschnittstelle explizit mit einer GUID zu definieren. Dann können alle Frühbuchten Clients die definierte Schnittstelle verwenden und sich nicht darum kümmern, sie während der Entwicklung auf zu ändern. Deshalb ist die empfohlene Option, keine der CLR zu sagen, um sie nicht automatisch für Sie zu generieren. Sie können die duale Schnittstelle dennoch implementieren, wenn Sie sie benötigen.

+0

Der Teil, den ich nicht klar ist, ist dies: 'Alle Änderungen in einer zukünftigen Version in das Layout des Typs oder einer beliebigen Basistypen wird COM-Clients zu brechen. Wenn ich eine Eigenschaft von int in double ändere, bricht der Client ab? Oder bedeutet es, dass wenn ich das .NET-Stück einfach neu kompiliere, der VB6-Client es nicht mehr konsumieren kann? – AngryHacker

+0

Solange Sie die Schnittstelle nicht ändern, sollten Sie in Ordnung sein. http://www.dotentininterop.com/faq/?q=ClassInterface – kemiller2002

+0

@Kevin, so einfach neu kompilieren meine .NET-Bibliothek wird nicht den Verbraucher als brechen? Und was bedeutet 'Ändern der Reihenfolge der Methoden 'wirklich? Bedeutung Ändern Sie die Reihenfolge der Methoden im Code? Ich weiß immer noch nicht, warum wir AutoDual vermeiden sollten. Ich denke, es versteht sich, dass, wenn Sie die Schnittstelle ändern, als der Verbraucher nicht arbeiten wird. In der VB6-Welt war das schon immer so. – AngryHacker

11

Ich habe einen zuverlässigen Weg gefunden, um sowohl Intellisense für .NET-Objekte in VB6 bereitzustellen als auch gleichzeitig die Schnittstelle nicht zu unterbrechen. Der Schlüssel besteht darin, jede öffentliche Methode/Eigenschaft in der Schnittstelle mit DispatchID zu markieren. Dann muss die Klasse von dieser Schnittstelle erben - wie unten beschrieben.

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

Was die Dispatch-ID gibt Ihnen die Möglichkeit, Elemente in der Klasse zu bewegen, plus Sie können nun neue Dinge in die Klasse hinzufügen und nicht die binäre Kompatibilität brechen.

Verwandte Themen