在WCF自托管服务中指定单例服务
问题描述:
我正在编写一个通过WCF公开服务的应用程序。该服务是自托管的(控制台应用程序),需要使用Singleton实例。我正在试图找出如何在服务配置中使用服务实现上的属性指定单身人士,而不使用。是否可以在没有属性的代码中指定单例?在WCF自托管服务中指定单例服务
感谢, 埃里克
答
您可以通过服务的实例的
ServiceHost
constructor强似一个类型。在这种情况下,你传递的实例将被用作单例。
编辑:
我以前的解决方案是行不通的。提供实例给ServiceHost
的构造函数仍然要求ServiceBehaviorAttribute
与InstanceContextMode.Single
。但是这一次应该工作:
var host = new ServiceHost(typeof(Service));
var behavior = host.Description.Behaviors.Find<ServiceBehaviorAttribute>();
behavior.InstanceContextMode = InstanceContextMode.Single;
host.Open();
ServiceBehaviorAttribute
即使你不指定,所以你只需要得到它,并更改默认值是包括在内。
答
如果你想这个迁入web.config
或app.config
,你可以使用自定义BehaviorExtensionElement
和IServiceBehavior
这样做:
的IServiceBehavior
真正分析从配置的值置于枚举并设置(以下@拉吉斯拉夫的答案):
public class InstanceContextServiceBehavior : IServiceBehavior
{
InstanceContextMode _contextMode = default(InstanceContextMode);
public InstanceContextServiceBehavior(string contextMode)
{
if (!string.IsNullOrWhiteSpace(contextMode))
{
InstanceContextMode mode;
if (Enum.TryParse(contextMode, true, out mode))
{
_contextMode = mode;
}
else
{
throw new ArgumentException($"'{contextMode}' Could not be parsed as a valid InstanceContextMode; allowed values are 'PerSession', 'PerCall', 'Single'", "contextMode");
}
}
}
public void AddBindingParameters(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase, Collection<ServiceEndpoint> endpoints, BindingParameterCollection bindingParameters)
{
var behavior = serviceDescription.Behaviors.Find<ServiceBehaviorAttribute>();
behavior.InstanceContextMode = _contextMode;
}
public void ApplyDispatchBehavior(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase)
{
return;
}
public void Validate(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase)
{
return;
}
}
扩展元素,可以从配置上拉,并把它传递给IServiceBehavior
:
public class InstanceContextExtensionElement : BehaviorExtensionElement
{
public override Type BehaviorType
{
get
{
return typeof(InstanceContextServiceBehavior);
}
}
protected override object CreateBehavior()
{
return new InstanceContextServiceBehavior(ContextMode);
}
const object contextMode = null;
[ConfigurationProperty(nameof(contextMode))]
public string ContextMode
{
get
{
return (string)base[nameof(contextMode)];
}
set
{
base[nameof(contextMode)] = value;
}
}
}
然后你可以用它在你的配置和使用它:
<extensions>
<behaviorExtensions>
<add name="instanceContext" type="FULLY QUALFIED NAME TO CLASS"/>
</behaviorExtensions>
</extensions>
...
<serviceBehaviors>
<behavior name="Default">
<instanceContext contextMode="Single"/>
我是新来的WCF和我有我想与配置,而不是在类的元数据来控制WCF服务。您能否提供您的解决方案的详细信息。 – SJunejo 2012-04-25 21:55:58
我需要强制'InstanceContextMode'到'PerCall',并且这个方法也适用于这个。 – Dan 2013-03-11 17:31:12