WCF初始化代码
本文关键字:代码 初始化 WCF | 更新日期: 2023-09-27 18:21:49
我创建了一个WCF服务,它从数据库中读取并发送回结果。出于性能原因,我希望在服务启动时缓存表(这发生在windows服务OnStart中)。但WCF中并没有构造函数(对吧?),所以我想到的最好的办法是创建一个Init()函数,并像下面这样调用它:
protected override void OnStart(string[] args)
{
mServiceHost = new ServiceHost(typeof(DLSService.DLSService), new Uri("http://localhost:8000/DLS"));
mServiceHost.AddServiceEndpoint(typeof(DLSService.IDLSService), new BasicHttpBinding(), "ServicesHost");
((DLSService.DLSService)mServiceHost.SingletonInstance).Init();
mServiceHost.Open();
}
但对我来说,使用SingletonInstance并转换为正确的类型似乎并不那么优雅。有没有更优雅的方法可以在WCF中实现类似构造函数的功能?
建议的最佳实践是在WCF中使用per-call激活模型,并保持服务完全无状态。
这意味着:每次客户端发出请求时,在服务器端,都会创建一个服务实现类的实例,进行请求的服务调用,然后再次销毁服务类。
因此,将初始化代码放入服务实现类构造函数将是一个非常糟糕的主意——它将为每个请求执行。
你可以做的是有某种逻辑(在你的服务类中,或者一些支持代码,例如某种管理接口),将你想要缓存的表加载到持久缓存中,例如AppFabric缓存。一旦完成,处理请求的多个服务实例就可以使用公共缓存来获得更好的性能。
这可以通过像MbCache这样的内存库来解决。我们正在做您想要做的事情;在应用程序启动时,我们调用要缓存的每个服务操作,MbCache缓存连续调用的结果(即没有数据库往返以获取结果),直到缓存到期。
MbCache确实有相当大的复杂性,但一旦运行起来,它就可以很好地工作,并为我们处理所有的缓存逻辑。
您可以使用IInstanceProvider
接口来创建服务,请阅读本文了解更多信息。下面是一个代码示例:
public class CustomInstanceProvider:IInstanceProvider
{
public object GetInstance(InstanceContext instanceContext)
{
return GetInstance(instanceContext, null);
}
public object GetInstance(InstanceContext instanceContext, System.ServiceModel.Channels.Message message)
{
return new DLSService.DLSService();
}
public void ReleaseInstance(InstanceContext instanceContext, object instance)
{
}
}
var mServiceHost = new ServiceHost(typeof(DLSService.DLSService), new Uri("http://localhost:8000/DLS"));
mServiceHost.AddServiceEndpoint(typeof(DLSService.IDLSService), new BasicHttpBinding(), "ServicesHost");
foreach (var channelDispatcher in mServiceHost.ChannelDispatchers.OfType<ChannelDispatcher>())
{
foreach (var endpointDispatcher in channelDispatcher.Endpoints)
{
endpointDispatcher.DispatchRuntime.InstanceProvider = new CustomInstanceProvider();
}
}
mServiceHost.Open();
使用框架4.5,您可以在服务实现代码中使用配置的功能:
http://msdn.microsoft.com/en-us/library/hh205277(v=vs.110).aspx。