我的应用程序作为 Windows 服务运行。它使用以下辅助方法动态创建 WCF 服务:
public static void StartWebService(string webServiceName, Type serviceContractType, Type serviceImplementationType)
{
if (string.IsNullOrEmpty(webServiceName)) return;
var baseAddress = GetWebServiceAddress(webServiceName);
var baseUri = new Uri(baseAddress);
lock (RunningWebServices)
{
if (RunningWebServices.ContainsKey(webServiceName))
return;
var webServiceHost = new ServiceHost(serviceImplementationType, baseUri);
var serviceBehaviour = new ServiceMetadataBehavior() { HttpGetEnabled = true };
webServiceHost.Description.Behaviors.Add(serviceBehaviour);
webServiceHost.AddServiceEndpoint(typeof(IMetadataExchange), MetadataExchangeBindings.CreateMexHttpBinding(), "mex");
var httpBinding = new BasicHttpBinding();
webServiceHost.AddServiceEndpoint(serviceContractType, httpBinding, baseAddress);
webServiceHost.Open();
RunningWebServices.Add(webServiceName, webServiceHost);
}
}
这些服务没有 .SVC 文件。还要清楚的是,这些是自托管服务,不在 IIS 下运行 - 它们在 WAS(Windows 激活服务)下运行。
现在我想控制实现类的实例化方式。听起来这可以通过ServiceHostFactory来完成。但是,我发现的所有关于此的文章都说,指定要使用的工厂的方法是将类型名称放在 .SVC 文件的 @ServiceHost 指令中。我没有这个文件!
有没有办法将我自己的 ServiceHost 工厂用于 WCF 服务,而没有在 WAS 下运行 SVC 文件?
更新以下答案
这是我结合 Carlos 解决方案的新辅助方法
public static void StartWebService(string webServiceName, Type serviceContractType, Type serviceImplementationType)
{
if (string.IsNullOrEmpty(webServiceName)) return;
var baseAddress = GetWebServiceAddress(webServiceName);
var baseUri = new Uri(baseAddress);
lock (RunningWebServices)
{
if (RunningWebServices.ContainsKey(webServiceName))
return;
var webServiceHost = new ServiceHost(serviceImplementationType, baseUri);
webServiceHost.Description.Behaviors.Add(new ServiceMetadataBehavior() { HttpGetEnabled = true });
webServiceHost.Description.Behaviors.Add(new CustomWebServiceBehavior());
webServiceHost.AddServiceEndpoint(typeof(IMetadataExchange), MetadataExchangeBindings.CreateMexHttpBinding(), "mex");
webServiceHost.AddServiceEndpoint(serviceContractType, new BasicHttpBinding(), baseAddress);
webServiceHost.Open();
RunningWebServices.Add(webServiceName, webServiceHost);
}
}
internal class CustomWebServiceBehavior : IServiceBehavior, IInstanceProvider
{
public void AddBindingParameters(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase, Collection<ServiceEndpoint> endpoints, BindingParameterCollection bindingParameters)
{
}
public void ApplyDispatchBehavior(ServiceDescription serviceDescription, ServiceHostBase serviceHost)
{
foreach (ChannelDispatcher cd in serviceHost.ChannelDispatchers)
{
foreach (EndpointDispatcher ed in cd.Endpoints)
{
ed.DispatchRuntime.InstanceProvider = this;
}
}
}
public void Validate(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase)
{
}
public object GetInstance(InstanceContext instanceContext, Message message)
{
return this.GetInstance(instanceContext);
}
public object GetInstance(InstanceContext instanceContext)
{
return // this is where I use my factory;
}
public void ReleaseInstance(InstanceContext instanceContext, object instance)
{
}
}