ASP.NET应用中的WCF客户端

从ASP.NET应用程序访问WCF web服务的最佳实践是什么?目前,在每个页面中,我都需要访问一个field

private readonly _serviceClient = new WCFServiceClient();

服务,并重复访问它的方法,每次调用时关闭它,每次出现故障时创建一个新实例。但是,我不知道是应该这样做,还是应该为每个方法调用创建一个新实例。这方面的最佳实践是什么?

3个回答

  1. 我做了一些类似于RubbleFord在他的评论中链接到的文章的事情,但是由于我处理的是多个服务,所以在最初创建时我使用ChannelFactory并缓存了返回的对象。然后根据需要创建新通道,使用它们,然后根据需要关闭/中止。helper方法位于一个单独的d ll中(我将使用Common作为示例):

    // bindingName refers to the Web.config binding section\'s name
    
    public static T GetFactoryChannel<T>(string address, string bindingName)
    
    {
    
        string key = typeof(T).Name;
    
    
    
        // OpenChannels is a property that refers to a Dictionary<string, object> holding the key and the channel factory
    
        if (!OpenChannels.ContainsKey(key))
    
        {  
    
            ChannelFactory<T> factory = new ChannelFactory<T>();
    
    
    
            factory.Endpoint.Address = new EndpointAddress(new System.Uri(address));
    
            factory.Endpoint.Binding = new NetTcpBinding(bindingName);
    
    
    
            OpenChannels.Add(key, factory);
    
        }
    
    
    
        T channel = ((ChannelFactory<T>)OpenChannels[key]).CreateChannel();
    
    
    
        ((IClientChannel(channel)).Open();
    
    
    
        return channel;
    
    }
    
    

    在我的客户机代码中,我会这样做(helper方法是通用的):

    IMyContract myContract = Common.GetChannelFactory<IMyContract>("net.tcp://someaddress/service", "MyNetTcpBinding");
    
    
    
    myContract.SomeMethod();
    
    
    
    Common.CloseChannel(myContract); // handles the necessary work to close or abort the channel.
    
    

    2我是根据一年前在web上发布的一些文章开发的,当时我刚开始使用WCF,它对我很有用。OpenChannels dictionary对象是存储的(在我的例子中,与AppDomain一起,因为我的大多数WCF服务都是WCF库),所以我只需要在给定的应用程序生命周期中创建每个通道工厂一次。您可以根据需要向GetFactoryChannel方法添加任何必要的逻辑(例如,凭据或不同类型的绑定)。我还应该注意,我没有向项目添加服务引用,而是使用svcutil生成的代理文件。这是3.5,顺便说一下。

  2. 看看文龙的博客。在.NET 3.5 Service PACK 1中,客户机代理扩展客户机基础共享一个静态信道工厂实例缓存应用程序-域。从我测试和实验中,信道工厂和通道的创建是WCF呼叫初始化的最耗资源的部分。通过使用“生成代理”,如果您使用的是运行时> = .NET 3.5 Service PACK 1,则已经完成了信道工厂部分。我已经看到,当服务契约变大时(更多的方法、更多的类型、更多的参数等等),创建通道变得更加困难和漫长。因此,我建议您保持服务契约的某种紧凑性。因此,基本上,如果您使用的是生成代理,我认为缓存/共享不会给您带来性能提升。对于同一服务的单个代码块中的连续调用,您最好使用相同的服务代理实例。每次呼叫创建一个不是最好的主意。

  3. 您可以在整个应用程序中使用服务cleint的单个isntance。如果您使用依赖注入,那么Unity或Spring.Net之类的任何IoC框架都将允许您将客户机配置为容器中的单例实例。创建单例实例不需要编写单独的代码。

Leave a Reply

Your email address will not be published. Required fields are marked *

You can use these HTML tags and attributes <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>