Расскажу о себе и почему меня заинтересовала эта тема.
Меня зовут Андрей Бутенко и последние 3 года занимаюсь внедрением и разработкой под Microsoft Dynamics CRM 4.0/2011. В реалиях нашего рынка превалирующей по количеству внедрений учётной системой является 1C и рано или поздно люди, которые занимаются внедрением CRM систем сталкиваются с задачами интеграции/синхронизации данных между CRM и учётных систем (в частном случае 1C). Вот и передо мной эта задача тоже встала.
1С начиная с версии 8.0 предоставляет более-менее адекватный механизм работы с данными и метаданными системы — COM объект.
В качестве примера кода поставлю задачу создания в 1С контрагента и получения его кода.
Как работа с 1С выглядела до появления .Net Framework 4.0 и типа dynamic:
Всё в принципе понятно, но такое количество рефлекссии на строку кода — немного ужасающе…
А теперь посмотрим тот же под, но написанный при помощи типов dynamic:
И результаты работы обеих программ:


Меня зовут Андрей Бутенко и последние 3 года занимаюсь внедрением и разработкой под Microsoft Dynamics CRM 4.0/2011. В реалиях нашего рынка превалирующей по количеству внедрений учётной системой является 1C и рано или поздно люди, которые занимаются внедрением CRM систем сталкиваются с задачами интеграции/синхронизации данных между CRM и учётных систем (в частном случае 1C). Вот и передо мной эта задача тоже встала.
1С начиная с версии 8.0 предоставляет более-менее адекватный механизм работы с данными и метаданными системы — COM объект.
В качестве примера кода поставлю задачу создания в 1С контрагента и получения его кода.
Как работа с 1С выглядела до появления .Net Framework 4.0 и типа dynamic:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Reflection;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
Type connector = Type.GetTypeFromProgID("V81.ComConnector");
if (connector == null)
throw new Exception(string.Format("COM Class Object {0} was not created or not registered in the system!", "V81.ComConnector"));
object connectorInstance = Activator.CreateInstance(connector);
if (connectorInstance == null)
throw new Exception(string.Format("Instance of class {0} was not created", "V81.ComConnector"));
//Подключение к базе
object _connection = connectorInstance.GetType().InvokeMember("Connect", BindingFlags.Public | BindingFlags.InvokeMethod | BindingFlags.Static, null, connectorInstance, new object[] { "File=\"C:\\tmp\";" });
//Получение справочника контрагентов
object _dictionary = _connection.GetType().InvokeMember("NewObject", BindingFlags.Public | BindingFlags.InvokeMethod | BindingFlags.Static, null, _connection, new object[] { "СправочникМенеджер.Контрагенты" });
//создание новой записи
object _record = _dictionary.GetType().InvokeMember("СоздатьЭлемент", BindingFlags.Public | BindingFlags.InvokeMethod | BindingFlags.Static, null, _dictionary, null);
//Заполнение поля наименование
_record.GetType().InvokeMember("НаименованиеПолное", BindingFlags.Public | BindingFlags.SetProperty, null, _record, new object[] { "Наша тестовая организация" });
//Сохранение записи
_record.GetType().InvokeMember("Write", BindingFlags.Public | BindingFlags.InvokeMethod | BindingFlags.Static, null, _record, null);
//Получение кода созданной организации
string code = _record.GetType().InvokeMember("Код", BindingFlags.GetProperty | BindingFlags.Public | BindingFlags.Static, null, _record, new object[] { }) as string;
//Выведение кода на консоль для проверки
Console.WriteLine(code);
Console.ReadKey();
}
}
}
Всё в принципе понятно, но такое количество рефлекссии на строку кода — немного ужасающе…
А теперь посмотрим тот же под, но написанный при помощи типов dynamic:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Reflection;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
Type connector = Type.GetTypeFromProgID("V81.ComConnector");
if (connector == null)
throw new Exception(string.Format("COM Class Object {0} was not created or not registered in the system!", "V81.ComConnector"));
dynamic connectorInstance = Activator.CreateInstance(connector);
if (connectorInstance == null)
throw new Exception(string.Format("Instance of class {0} was not created", "V81.ComConnector"));
//Подключение к базе
dynamic _connection = connectorInstance.Connect("File=\"C:\\tmp\";");
//Получение справочника контрагентов
dynamic _dictionary = _connection.NewObject("СправочникМенеджер.Контрагенты");
//создание новой записи
dynamic _record = _dictionary.СоздатьЭлемент();
//Заполнение поля наименование
_record.НаименованиеПолное = "Наша тестовая организация";
//Сохранение записи
_record.Write();
//Получение кода созданной организации
string code = _record.Код as string;
//Выведение кода на консоль для проверки
Console.WriteLine(code);
Console.ReadKey();
}
}
}
И результаты работы обеих программ:

