Domanda

Sto tentando di restituire una raccolta di reparti da un assembly .NET che verrà utilizzata da ASP tramite interoperabilità COM. Utilizzando .NET vorrei solo restituire una raccolta generica, ad es. List<Department>, ma sembra che i generici non funzionino bene con l'interoperabilità COM. Quindi, quali sono le mie opzioni?

Vorrei sia scorrere l'elenco sia essere in grado di accedere a un elemento per indice. Devo ereditare da IList, implementare un IList<Department>, List[index] o un'altra interfaccia o esiste un modo migliore? Idealmente, preferirei non dover implementare una raccolta personalizzata per ogni tipo di elenco di cui ho bisogno. Inoltre, <=> funzionerà anche con l'interoperabilità COM?

Grazie, Mike

Componenti .NET di esempio (C #):

public class Department {
    public string Code { get; private set; }
    public string Name { get; private set; }
    // ...
}

public class MyLibrary {
    public List<Department> GetDepartments() {
        // return a list of Departments from the database
    }
}

Esempio di codice ASP:

<%
Function PrintDepartments(departments)
    Dim department
    For Each department In departments
        Response.Write(department.Code & ": " & department.Name & "<br />")
    Next
End Function

Dim myLibrary, departments
Set myLibrary = Server.CreateObject("MyAssembly.MyLibrary")
Set departments = myLibrary.GetDepartments()
%>
<h1>Departments</h1>
<% Call PrintDepartments(departments) %>
<h1>The third department</h1>
<%= departments(2).Name %>

Domande correlate:

È stato utile?

Soluzione

Dopo ulteriori ricerche e prove ed errori, penso di aver trovato una soluzione utilizzando System.Collections.ArrayList. Tuttavia, questo non funziona con l'ottenimento di un valore per indice. Per fare ciò, ho creato una nuova classe ComArrayList che eredita da ArrayList e aggiunge nuovi metodi GetByIndex e SetByIndex.

Collezione compatibile con l'interoperabilità COM:

public class ComArrayList : System.Collections.ArrayList {
    public virtual object GetByIndex(int index) {
        return base[index];
    }

    public virtual void SetByIndex(int index, object value) {
        base[index] = value;
    }
}

Componente .NET aggiornato MyLibrary.GetDepartments:

public ComArrayList GetDepartments() {
    // return a list of Departments from the database
}

ASP aggiornato:

<h1>The third department</h1>
<%= departments.GetByIndex(2).Name %>

Altri suggerimenti

Dato che stai utilizzando solo i dati in ASP, ti suggerirei di restituire Department[]. Questo dovrebbe essere mappato direttamente a un SAFEARRAY in COM. Supporta anche l'enumerazione e l'accesso indicizzato.

public Department[] GetDepartments() {
    var departments = new List<Department>();
    // populate list from database
    return departments.ToArray();
}

Nel tuo codice ASP, non potresti farlo?

<h1>The third department</h1>
<%= departments.Item(2).Name %>

So che in VB .NET, gli indicizzatori C # sono supportati tramite " Item " proprietà, quindi la stessa idea potrebbe funzionare in ASP.

Ho cercato di risolvere questo stesso problema in vb.net (non parla fluentemente C #).

Poiché List (Of T) supporta l'interfaccia IList, per l'interfaccia COM per i miei oggetti ho provato a specificare

Public Class MyClass
...
   Private _MyList As List(of MyObject)
   Public ReadOnly Property MyList As IList Implements IMyClass.MyList
    Get
        Return _MyList
    End Get
   End Property

e quindi specificando nell'interfaccia pubblica che COM vede

ReadOnly Property MyList As IList

Questo sembra funzionare bene da un classico client ASP che crea un'istanza dell'oggetto, chiama una funzione generatore e quindi legge la proprietà MyList come un array.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top