Tricky IDisposable Issue

此生再无相见时 提交于 2019-12-05 14:40:11

Something like the following may help

public static void UsePrestoService(Action<IPrestoService> callback)
{
    using (var channelFactory = new WcfChannelFactory<IPrestoService>(new NetTcpBinding()))
    {
        var endpointAddress = ConfigurationManager.AppSettings["prestoServiceAddress"];
        IPrestoService prestoService = channelFactory.CreateChannel(new EndpointAddress(endpointAddress));  
        //Now you have access to the service before the channel factory is disposed.  But you don't have to worry about disposing the channel factory.
        callback(prestoService);
    }
}

UsePrestoService(service => this.Applications = new ObservableCollection<Application>(service.GetAllApplications().ToList()));

Side note:

I haven't used this pattern much with disposables because I haven't found too much of a need for disposables recently. However, in theory I think I like this pattern, taking a callback that executes inside of a using block, when working with disposables for two reasons:

  1. It's simple
  2. It forces consumers of IDisposables to dispose of the instances correctly...Although I agree (I think) with the C#'s team to not raise compiler warnings when IDisposables aren't disposed of in all execution paths, it's still a bit worrisome.

Are you sure to use service locator pattern there? Beside it is an anti-pattern, by using Invoke<T> and Func<T, TResult>, I think there will be some confusion in the future use. Furthermore, I don't think that this way will separate the usage of service to another layer.

I think this approach, by returning the result, is having more SOC than using Func<T, TResult>.

public static class PrestoWcf
{
    public static IEnumerable<Application> PrestoService
    {
        get
        {
            IEnumerable<Application> appList;
            using (var channelFactory = new WcfChannelFactory<IPrestoService>(new NetTcpBinding()))
            {
                var endpointAddress = ConfigurationManager.AppSettings["prestoServiceAddress"];    
                appList = prestoService.GetAllApplications().ToArray(); //you can ignore the .ToArray, I just not sure whether the enumerable still keep the reference to service
            }
            return appList;
        }
    }
}

Cleaner, but still i don't suggest to use static method.

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!