我有一个WCF服务,有时在IIS中托管,有时托管在Windows服务中。这对于我的应用程序的不同部署选项是必需的。在服务对象中确定托管位置的好方法是什么?
我想要的原因是当我的服务托管在IIS中时,它以正常方式从web.config文件获取连接字符串信息。当它由Windows服务托管时,它以不同的方式获取配置信息(来自注册表中的信息)。在我的服务对象的构造函数中,我想要注意从哪里获取连接字符串信息,例如像这样的东西:
public void MyServiceObject()
{
_hostedInIis = isHostedInIis();
}
private string ConnectionString()
{
if (_hostedInIis)
return ConfigurationManager.ConnectionStrings["MyDatabase"].ConnectionString;
else
return GetConnectionStringFromRegistry();
}
或者,当我在Windows服务中托管它时,有没有办法将一些配置信息传递给它?例如传递它的连接字符串或一个标志,说它托管在Windows服务中。
答案 0 :(得分:2)
当我设置一个服务以独立运行配置时,或者在没有配置文件的IIS下运行时,我需要类似的东西。我最终使用自定义ServiceHostFactory
来处理IIS案例。在工厂构造ServiceHost
之后,它将自定义配置对象添加到其Extensions
属性,其中包含我无法放入web.config的信息。像这样:
protected override ServiceHost CreateServiceHost(Type serviceType, Uri[] baseAddresses)
{
var host = base.CreateServiceHost(serviceType, baseAddresses);
host.Extensions.Add(new CustomConfigurer());
return host;
}
然后在该服务的.svc文件中,您可以指定自定义工厂,IIS将只使用它:
<%@ ServiceHost Service="..." Factory="..." %>
调用服务操作时,它可以在主机的扩展名上查找配置对象:
public int Add(int x, int y)
{
var config = OperationContext.Current.Host.Extensions.Find<CustomConfigurer>();
if (config == null)
{
// Load elsewhere
}
}
答案 1 :(得分:1)
我选择子类化我的服务类,并在我的Windows服务中托管时使用子类。子类的唯一区别是它知道从注册表而不是默认位置获取其配置信息:配置管理器。这比我最初想要的更好,因为服务不需要知道它在哪里。
答案 2 :(得分:-1)
probabily不是最好的方法,但你可以检查通常出现在Asp.net应用程序中的HttpContext
private string ConnectionString()
{
if (HttpContext.Current!=null)
return ConfigurationManager.ConnectionStrings["MyDatabase"].ConnectionString;
else
return GetConnectionStringFromRegistry();
}