C# WCF初始化代码

C# WCF初始化代码,c#,.net,wcf,C#,.net,Wcf,我已经创建了一个WCF服务,它从数据库读取数据并返回结果。出于性能原因,我希望在服务启动时缓存表(这发生在windows服务启动时)。但WCF中没有构造函数(对吧?),所以我想到的最好的办法是创建一个Init()函数并调用它,如下所示: protected override void OnStart(string[] args) { mServiceHost = new ServiceHost(typeof(DLSService.DLSService), new Uri("http://

我已经创建了一个WCF服务,它从数据库读取数据并返回结果。出于性能原因,我希望在服务启动时缓存表(这发生在windows服务启动时)。但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();
}
但是使用单音站姿和正确的类型对我来说似乎并不那么重要。
有没有更优雅的方法来实现WCF中类似构造函数的功能?

建议的最佳实践是在WCF中使用每次调用的激活模型,并保持服务完全无状态

这意味着:每次客户端发出请求时,在服务器端,都将创建服务实现类的实例,发出请求的服务调用,然后服务类将再次被销毁

因此,将您的初始化代码放入服务实现类构造函数将是一个非常糟糕的主意——它将针对每个请求执行


您可以做的是使用某种逻辑(在您的服务类中,或者在一些支持代码中,例如某种管理接口),将要缓存的表加载到持久缓存中,例如AppFabric缓存。一旦完成,处理请求的多个服务实例可以使用该公共缓存来获得更好的性能。

您可以使用
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();
公共类CustomInstanceProvider:IInstanceProvider
{
公共对象GetInstance(InstanceContext InstanceContext)
{
返回GetInstance(instanceContext,null);
}
公共对象GetInstance(InstanceContext InstanceContext,System.ServiceModel.Channel.Message)
{
返回新的DLSService.DLSService();
}
public void ReleaseInstance(InstanceContext InstanceContext,对象实例)
{            
}
}
var mServiceHost=新服务主机(typeof(DLSService.DLSService),新Uri(“http://localhost:8000/DLS"));   
mServiceHost.AddServiceEndpoint(typeof(DLSService.IDLSService),新的BasicHttpBinding(),“ServicesHost”);
foreach(mServiceHost.ChannelDispatchers.OfType()中的var channelDispatcher)
{
foreach(channelDispatcher.Endpoints中的var endpointDispatcher)
{
endpointDispatcher.DispatchRuntime.InstanceProvider=新的CustomInstanceProvider();
}
}
mServiceHost.Open();
这可以通过一个库来解决,比如。我们所做的正是你所期待的;在应用程序启动时,我们调用要缓存的每个服务操作,MbCache缓存连续调用的结果(即没有数据库往返来获取结果),直到缓存过期


MbCache确实具有相当大的复杂性,但一旦它运行起来,它就可以很好地为我们处理所有缓存逻辑。

使用framework 4.5,您可以在服务实现代码中使用配置功能:


.

好的观点。对于一个服务实例,您将很难编写错误处理。如果服务处于故障状态,则需要在每次调用时编写恢复代码。使用每次呼叫服务,您只需关闭出现故障的服务并启动一个新的服务。