进入新的系列:.net connector 3.0,简称 Nco3.0。Nco3.0 是 SAP 针对 .net 平台提供的编程接口,由 Nco1.0/Nco2.0 演变而来。如果使用 .net 平台编程,推荐使用 NCo3.0。3.0 版与之前1.0/2.0 版本比较,不管是 API 还是架构,都重新设计过,也借鉴了 Jco3.0 的设计,所以相对来说更为成熟,也为程序员提供更好的控制性和方便性。
Nco3.0 的优点
- 更加稳定、健壮、安全。关于安全,后面会有相关介绍。
- 重新设计了 SAP connection 的处理方法:Nco3.0 中开发者不需要自己去管理与 SAP 的连接 (Connection):不需要打开连接、关闭连接、Connection 对象销毁等等。所有这一切由 .Net connectior 3.0 来管理。
- 增强对大量交易数据(不是 big data,而是 mass transactions 或 heavy load scenario) 处理的能力
- 减少内存耗用
- 不绑定 Visual Studio 版本
.Net connector 3.0 下载和安装
下载地址: https://service.sap.com/connectors。 安装比较简单,其实就是解压,解压出几个文件。我们在程序中主要使用 sapnco.dll
和 sapnco_utils.dll
这两个动态链接库。以 Win7 (32位)为例,默认的安装路径是: C:\Program Files (x86)\SAP\SAP_DotNetConnector3
。
使用 Nco 的环境准备
1、添加引用
添加对 sapnco.dll
和 sapnco_utils.dll
的引用。
2、导入 Nco 3.0 的 namespace
Nco 3.0 只有一个 namespace:SAPP.Middleware.Connector
,在需要用到 Nco 3.0 对象的代码中导入这个namespace
using SAP.Middleware.Connector;
通过 RfcDestination
建立与 SAP 系统的连接
RfcDestination
代表后端 SAP 系统。前面我们说到,在 RFC 技术中, 一般通过 Connection
对象连接到 SAP 系统,Nco3.0 设计的一个重大改变就是:开发者不用再关心与 SAP 的连接,RfcDestination
对象管理连接相关的工作。
Nco3.0 提供 RfcDestinationManager
类的 GetDestination
方法来创建 RfcDestination
实例,并且保证只有一个 RfcDestination
实例 (单例模式):
// 方法一
public static RfcDestination GetDestination(RfcConfigParameters parameters);
// 方法二
public static RfcDestination GetDestination(string destinationName);
方法 1 的参数为 RfcConfigParameters
,这个参数包含必要的登录参数。
方法 2 的参数为连接字符串。这个连接字符串来自于开发者自定义的,实现了 IDestinationConfiguration
接口的类。IDestinationConfiguration
接口有一个 GetParameters()
方法。实现 GetParameters()
方法的时候,需要定义字符串 destinationName
。然后,
RfcDestinationManager.GetDestination()
方法会自动调用 GetParameters()
方法,获取其中的 logon parameters。开发者可以在GetParameters()
方法中确定,是将登录 SAP 所需要的参数保存在文件中、还是提供一个 UI 界面来填写登录信息,开发人员具有较大的自由度。
设置 RfcConfigParameters
参数示例
文件:RfcDestinationDemo.cs
using SAP.Middleware.Connector;
namespace Nco01
{
public class RfcDestinationDemo
{
private RfcConfigParameters GetConfigParams()
{
RfcConfigParameters configParams = new RfcConfigParameters();
// Name property is neccessary, otherwise, NonInvalidParameterException will be thrown
configParams.Add(RfcConfigParameters.Name, "ECC");
configParams.Add(RfcConfigParameters.AppServerHost, "192.168.65.100");
configParams.Add(RfcConfigParameters.SystemNumber, "00"); // instance number
configParams.Add(RfcConfigParameters.SystemID, "D01");
configParams.Add(RfcConfigParameters.User, "STONE");
configParams.Add(RfcConfigParameters.Password, "xxx");
configParams.Add(RfcConfigParameters.Client, "001");
configParams.Add(RfcConfigParameters.Language, "EN");
configParams.Add(RfcConfigParameters.PoolSize, "5");
configParams.Add(RfcConfigParameters.MaxPoolSize, "10");
configParams.Add(RfcConfigParameters.IdleTimeout, "30");
return configParams;
}
public RfcDestination GetDestination()
{
RfcConfigParameters configParams = this.GetConfigParams();
RfcDestination dest = RfcDestinationManager.GetDestination(configParams);
return dest;
}
public void PingDestination()
{
RfcDestination destination = this.GetDestination();
destination.Ping();
}
}
}
单元测试:
using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Nco01;
namespace UnitTestProject1
{
[TestClass]
public class TestRfcDestinationDemo
{
[TestMethod]
public void TestPing()
{
RfcDestinationDemo rfc = new RfcDestinationDemo();
rfc.PingDestination();
}
}
}
定义字符串 destinationName
示例
定义一个类 DestinationConfig
,实现 IDestinationConfiguration
接口,起始代码如下:
// File name: DestinationConfig.cs
using System;
using SAP.Middleware.Connector;
namespace Nco01
{
class DestinationConfig : IDestinationConfiguration
{
public bool ChangeEventsSupported()
{
throw new NotImplementedException();
}
public event RfcDestinationManager.ConfigurationChangeHandler ConfigurationChanged;
public RfcConfigParameters GetParameters(string destinationName)
{
throw new NotImplementedException();
}
}
}
对代码进行改写,在 getParameters()
方法中,设置 logon parameters,并设置 destinationName 为 ECC 。
using System;
using SAP.Middleware.Connector;
namespace Nco01
{
class DestinationConfig : IDestinationConfiguration
{
public bool ChangeEventsSupported()
{
return false; // 不支持ChangeEvent
}
public event RfcDestinationManager.ConfigurationChangeHandler ConfigurationChanged;
public RfcConfigParameters GetParameters(string destinationName)
{
// get logon parameteres according to destinationName
// the following is logon paramters for 'ECC'
if ("ECC".Equals(destinationName)) {
RfcConfigParameters configParams = new RfcConfigParameters();
configParams.Add(RfcConfigParameters.AppServerHost, "192.168.65.100");
configParams.Add(RfcConfigParameters.SystemNumber, "00"); // instance number
configParams.Add(RfcConfigParameters.SystemID, "D01");
configParams.Add(RfcConfigParameters.User, "STONE");
configParams.Add(RfcConfigParameters.Password, "xxx");
configParams.Add(RfcConfigParameters.Client, "001");
configParams.Add(RfcConfigParameters.Language, "EN");
configParams.Add(RfcConfigParameters.PoolSize, "5");
configParams.Add(RfcConfigParameters.MaxPoolSize, "10");
configParams.Add(RfcConfigParameters.IdleTimeout, "30");
return configParams;
}
else {
return null;
}
}
}
}
连接模块代码:
RfcDestinationUsingConfig.cs
using SAP.Middleware.Connector;
namespace Nco01
{
public class RfcDestUsingConfig
{
private RfcDestination destination;
// initialize in constructor
public RfcDestUsingConfig()
{
DestinationConfig destConfig = new DestinationConfig();
RfcDestinationManager.RegisterDestinationConfiguration(destConfig);
destination = RfcDestinationManager.GetDestination("ECC");
}
public RfcDestination GetConnection()
{
return destination;
}
public void PingDestination()
{
destination.Ping();
}
}
}
在构造器中初始化 RfcDestination
,搞得这么复杂,主要就是安全原因。有了 ECC 这个 destinationName,就可以自动调用 DestinationConfig
类的 GetParameters()
方法,获取 logon parameters 进行注册。开发人员呢,只需要关心 destination 就行。
单元测试:
using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Nco01;
namespace UnitTestProject1
{
[TestClass]
public class TestRfcDestinationDemo
{
[TestMethod]
public void TestPing()
{
RfcDestinationDemo rfc = new RfcDestinationDemo();
rfc.PingDestination();
}
}
}