在作为Windows服务托管的WCF类库项目中使用SqlDependency

时间:2018-11-30 08:54:05

标签: c# wcf windows-services sqldependency

我已经使用SqlDependency创建了一个通知服务,用于通知其他服务特定表中的更改。这是在Visual Studio的Windows服务模板中完成的。因此,在OnStart事件中,创建SqlDependency的订阅,在OnStop事件中,取消订阅。

上述解决方案运行良好。

现在,由于某些原因,我必须将其设为WCF类库项目并将其托管为Windows服务。我想不出在这种情况下可以进行SqlDependency的订阅和取消订阅的地方。

启动Windows服务时,必须自动完成订阅。

注意:我有一台通用的Windows服务主机,它将托管我的所有WCF类库项目,并且在那里不能做很多事情。

对此有任何解决方案或解决方法吗?

1 个答案:

答案 0 :(得分:0)

我希望我能解决您的问题。您拥有WCF库中的所有逻辑,但不知道如何在将承载WCF服务的Windows Service启动时同步您的订阅和退订SqlDependancy事件。

我的想法是使用ServiceHostFactory创建服务实例,并钩住服务的打开和关闭事件,从那里调用所有必要的构造函数和连接器。

我的大部分回答来自https://www.rdocumentation.org/packages/kernlab/versions/0.9-27/topics/predict.ksvm篇精彩而冗长的文章,内容涉及托管WCF服务,链接直接指向您所关注的主题。 thisServiceHost类的一些其他文档。

请记住,这不是一个完整的代码,您只能复制/粘贴它,而只是演示用法。

以下是Windows服务的示例:

public partial class YourWindowsService : ServiceBase
{

    // It's your choice where to create this instance, I used constructor injection here arbitrarily
    private readonly YourWCFServiceFactory serviceFactory;   

    private ServiceHost host;

    public YourWindowsService(YourWCFServiceFactory serviceFactory)
    {
        InitializeComponent();
        this.serviceFactory = serviceFactory;
    }

    protected override void OnStart(string[] args)
    {
        Type serviceType = typeof(YourService);
        host = serviceFactory.CreateServiceHost(serviceType, new string[] { "yourBaseUri" });
        host.Open();
    }

    protected override void OnStop()
    {
        if(host != null)
           host.Close();
    }
}

还有一个工厂的例子:

public class YourWCFServiceFactory: ServiceHostFactory
{
    protected override ServiceHost CreateServiceHost(Type serviceType, Uri[] baseAddresses)
    {
        ServiceHost host = base.CreateServiceHost(serviceType, baseAddresses);
        host.Opening += new EventHandler(host_Opening);
        host.Closing += new EventHandler(host_Closing);
        return host;
    }

    private void host_Opening(object sender, EventArgs e)
    {
        // Initialization here
    }

    private void host_Opening(object sender, EventArgs e)
    {
        // Cleanup here
    }
}