CLR Interop é o caminho inverso do .Net Business connector, que apresentei em outro post aqui no blog. Ele permite utilizar assemblies gerenciados (dll criadas em .net) em código X++ executado dentro do Dynamics AX. vou mostrar um exemplo no qual utilizo a biblioteca System.Data do .Net Framework 2.0 para acessar dados em um banco de dados SQL Server externo.
Para podermos utilizar o assembly temos que adicionar uma referência no AX. Para isto encontre o nó do AOT chamado references, clique com a direita e selecione a opção Add reference. Selecione o(s) assembly(ies) desejado(s) e clique ok. As fotos abaixo mostram o processo visualmente.
Figura 1: Menu para adicionar referências

Figura 2: Selecionando os assemblies desejados

Após este processo o assembly e suas classes podem ser utilizadas em qualquer código X++. No código abaixo utilizo objetos da biblioteca System.Data, SqlConnection, SqlCommando, SqlDataReader, para ler a tabela de produtos do banco de dados AdventureWorks (um BD exemplo da Microsoft, veja as intruções para instalá-lo)
//Objects for external database access
System.Data.SqlClient.SqlConnection connection;
System.Data.SqlClient.SqlDataReader dataReader;
System.Data.SqlClient.SqlCommand command;
System.Exception e;
str commandString;
str errorMessage;
int64 itemID;
str itemName;
;
connection = new System.Data.SqlClient.SqlConnection("Server=localhost;Database=adventureworks;Trusted_Connection=yes;");
try
{
connection.Open();
commandString = "SELECT TOP 10 ProductID, Name FROM Production.Product"
command = new System.Data.SqlClient.SqlCommand(commandString, connection);
dataReader = command.ExecuteReader();
while(dataReader.Read())
{
print dataReader.get_Item(1);
}
pause;
}
catch
{
e = CLRInterop::getLastException();
while(e != null)
{
errorMessage += e.get_Message();
e = e.get_InnerException();
}
throw error(errorMessage);
}
dataReader.Dispose();
command.Dispose();
connection.Dispose();
Os erros que ocorrerem no código gerenciado devem ser tratados em separado, utilizando o objeto System.Exception.
Outro detalhe é que sempre que uma classe gerenciada tiver o método dispose() este deve ser executado ao final de sua utilização. Este método libera os recursos não gerenciados pelo .Net Framework.