在我们的SharePoint / ASP.NET环境中,我们有一系列数据检索器类,它们都是从公共接口派生的.我被分配了创建数据检索器的任务,该数据检索器可以使用WCF与其他SharePoint农场进行远程通信.我现在实施的方式是一个单一的ChannelFactory< T>在静态构造函数中创建,然后由远程数据检索器的每个实例重用,以创建单个代理实例.我认为这样做会很好,因为ChannelFactory只能在一个应用程序域中被实例化一次,其创建是
guaranteed to be thread-safe.我的代码看起来像这样:
public class RemoteDataRetriever : IDataRetriever { protected static readonly ChannelFactory<IRemoteDataProvider> RequestChannelFactory; protected IRemoteDataProvider _channel; static RemoteDataRetriever() { WSHttpBinding binding = new WSHttpBinding( SecurityMode.TransportWithMessageCredential,true); binding.Security.Transport.ClientCredentialType = HttpClientCredentialType.None; binding.Security.Message.ClientCredentialType = MessageCredentialType.Windows; RequestChannelFactory = new ChannelFactory<IRemoteDataProvider>(binding); } public RemoteDataRetriever(string endpointAddress) { _channel = RemoteDataRetriever.RequestChannelFactory. CreateChannel(new EndpointAddress(endpointAddress)); } }
我的问题是,这是一个很好的设计吗?我想,一旦创建了ChannelFactory,我不需要担心线程安全,因为我只是使用它来调用CreateChannel(),但我错了?是否改变状态或以其他方式做一些有趣的幕后可能会导致线程问题?另外,我需要将某些代码放在手动处理ChannelFactory的某个地方(static finalizer?),或者我可以假设每当IIS重新启动时,它会为我做所有的清理工作?
从“这是单身设计好”,你的单身人士的执行是好的.它是线程安全的,并且ChannelFactory< T>也是线程安全的.
您也不必担心资源清理.假设ChannelFactory< T>遵循Microsoft’s guidelines for implementing IDisposable,那么你不会有某种泄漏的问题.当应用程序域被拆除时,将创建一个垃圾收集,并且在这一点上将清除所有内容. ChannelFactory< T>的终结器将进行清理通常在调用Dispose中执行.
然而,从“我应该缓存ChannelFactory< T>”从这个角度来说,很难说,因为你没有指出你的.NET版本.但是,您指出的文章指出,如果您使用的是.NET 3.0 SP1或更高版本,则您实际上不需要这样做,您可以创建代理(假设它们源自ClientBase< T>),您需要它客户端代码,而不是通过这样的工厂模式.