【问题标题】:How to consume a LOB Adapter SDK-based design-time interfaces如何使用基于 LOB 适配器 SDK 的设计时接口
【发布时间】:2014-06-30 19:17:29
【问题描述】:

我正在尝试构建一个基于 Web 的 GUI 来使用基于 LOB Adapter SDK 的自定义连接器。 我特别想使用IMetadataResolverHandler接口浏览元数据。

我有两个问题:

第一个问题发生在尝试实例化自定义适配器时。我的计划是获取一个IConnectionFactory接口的实例,通过它我可以得到一个新的IConnection并连接到目标LOB系统。

由于Adapter 基类中最有趣的方法受到保护,我似乎只能使用反射来成功(请参阅下面的示例代码)。

第二个问题发生在尝试从目标系统浏览元数据时。 IMetadataResolverHandler 接口上的方法 Browse 需要一个 MetadataLookup 对象的实例,我不知道如何获得。

请看下面的示例代码:

    static void Main(string[] args)
    {
        var extension = new SqlAdapterBindingElementExtensionElement();
        var adapter = (Adapter) Activator.CreateInstance(extension.BindingElementType);

        var isHandlerSupportedMethodInfo = adapter.GetType().GetMethod("IsHandlerSupported", BindingFlags.NonPublic | BindingFlags.Instance);
        var buildConnectionUri = adapter.GetType().GetMethod("BuildConnectionUri", BindingFlags.NonPublic | BindingFlags.Instance);
        var buildConnectionFactory = adapter.GetType().GetMethod("BuildConnectionFactory", BindingFlags.NonPublic | BindingFlags.Instance);

        if (isHandlerSupportedMethodInfo == null || buildConnectionUri == null || buildConnectionFactory == null)
        {
            Console.WriteLine("Not a LOB adapter.");
            Environment.Exit(1);
        }

        var isHandlerSupportedTHandler = isHandlerSupportedMethodInfo.MakeGenericMethod(typeof(IMetadataResolverHandler));
        var isMetadataBrowseSupported = (bool)isHandlerSupportedTHandler.Invoke(adapter, new object[] { });

        if (!isMetadataBrowseSupported)
        {
            Console.WriteLine("Metadata retrieval not supported.");
            Environment.Exit(1);
        }

        var bindingElement = (SqlAdapterBindingElement)adapter;
        bindingElement.AcceptCredentialsInUri = false;
        bindingElement.InboundOperationType = InboundOperation.TypedPolling;
        bindingElement.PolledDataAvailableStatement = "EXEC [dbo].[usp_IsDataAvailable]";
        bindingElement.PollingStatement = "EXEC [dbo].[usp_SelectAvailableData]";
        bindingElement.PollingIntervalInSeconds = 10;

        var binding = new CustomBinding();
        binding.Elements.Add(adapter);

        var parameters = new BindingParameterCollection();

        var context = new BindingContext(binding, parameters);

        var credentials = new ClientCredentials();
        credentials.UserName.UserName = "username";
        credentials.UserName.Password = "password";

        var address = (ConnectionUri) buildConnectionUri.Invoke(adapter, new []{ new Uri("mssql://azure.database.windows.net//SampleDb?InboundId=uniqueId")});

        var connectionFactory = (IConnectionFactory)buildConnectionFactory.Invoke(adapter, new object[] { address, credentials, context });
        var connection = connectionFactory.CreateConnection();

        connection.Open(TimeSpan.MaxValue);

        MetadataLookup lookup = null; // ??
        var browser = connection.BuildHandler<IMetadataBrowseHandler>(lookup);

        connection.Close(TimeSpan.MaxValue);
    }

【问题讨论】:

    标签: wcf-lob-adapter


    【解决方案1】:

    回答我自己的问题时,我通过检查“使用适配器服务”向导的代码找到了答案。关键是使用IMetadataRetrievalContract 接口,该接口在内部使用最多三个LOB-SDK 接口实现,尤其是IMetadataResolverHandler

    这是无需反射即可工作的代码:

    var extension = new SqlAdapterBindingElementExtensionElement();
    var adapter = (Adapter) Activator.CreateInstance(extension.BindingElementType);
    
    var bindingElement = (SqlAdapterBindingElement)adapter;
    bindingElement.AcceptCredentialsInUri = false;
    bindingElement.InboundOperationType = InboundOperation.TypedPolling;
    bindingElement.PolledDataAvailableStatement = "EXEC [dbo].[usp_IsDataAvailable]";
    bindingElement.PollingStatement = "EXEC [dbo].[usp_SelectAvailableData]";
    bindingElement.PollingIntervalInSeconds = 10;
    
    var binding = new CustomBinding();
    binding.Elements.Add(adapter);
    
    const string endpoint = "mssql://azure.database.windows.net//SampleDb?InboundId=unique";
    var factory = new ChannelFactory<IMetadataRetrievalContract>(binding, new EndpointAddress(new Uri(endpoint)));
    factory.Credentials.UserName.UserName = "username";
    factory.Credentials.UserName.Password = "password";
    
    factory.Open();
    var channel = factory.CreateChannel();
    ((IChannel)channel).Open();
    
    var metadata = channel.Browse(MetadataRetrievalNode.Root.DisplayName, 0, Int32.MaxValue);
    
    ((IChannel) channel).Close();
    factory.Close();
    

    【讨论】:

      猜你喜欢
      • 2022-10-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-05-16
      • 2016-01-03
      • 2013-06-18
      • 1970-01-01
      • 2017-06-06
      相关资源
      最近更新 更多