how to host custom wcf applicaion(server) on IIS7.5? - wcf

I've used custom wcf applicaion as wcf server by using:
ServiceHost<AlertService> alertServiceHost = new ServiceHost<AlertService>();
configuredEndpoints = alertServiceHost.Description.Endpoints;
alertServiceHost.Open();
Now, I have a problem with deployment on production which is IIS7.5.
I have no idea how to deploy on IIS. Because I only know that I have to create svc file for hosting on IIS. Now, I only have console application working as wcf service.
How can I transform it to deploy on IIS?
Thank you.

If you want to use a custom service host in a IIS hosting scenario, you need to supply a custom ServiceHostFactory that will return that type of service host, and configure that service host factory in your SVC file.
Basically, your custom service host factory must descend from ServiceHostFactory and override one method that returns an instance of your custom service host - something along the lines of:
public class MyOwnServiceHostFactory : ServiceHostFactory
{
protected override ServiceHost CreateServiceHost(Type t, Uri[] baseAddresses)
{
return new MyOwnCustomServiceHost(t, baseAddresses);
}
public override ServiceHostBase CreateServiceHost(string service, Uri[] baseAddresses)
{
// The service parameter is ignored here because we know our service.
ServiceHost serviceHost = new ServiceHost(typeof(HelloService), baseAddresses);
return serviceHost;
}
}
And in your SVC file, you now need to have:
<%# ServiceHost Language="C#" Debug="true"
Service="YourNamespace.YourService"
Factory="YourNamespace.MyOwnServiceHostFactory" %>
Read more about:
ServiceHostFactory on MSDN
Extending hosting using ServiceHostFactory

When hosting in IIS you don't create ServiceHost by yourselves. It is reponsibility of IIS and reason why .svc file exists. Svc file instructs worker process how and which service should be hosted.
Svc file consists of simple directive (markup):
<%# ServiceHost Language="C#" Debug="true" Service="MyNamespace.MyService" CodeBehind="MyService.svc.cs" %>
This is example of .svc file hosting locally create service but you can omit CodeBehind attribute and use full type description in Service attribute to host service class from another assembly.
Also check How to: Host WCF service in IIS.

Related

Configuring a WCF and StructureMap ServiceHostFactory from code

I am creating a custom ServiceHost object and configuring it from code. My service is using InstanceContextMode.Single and ConcurrencyMode.Multiple and is hosted in a windows service.
As stated in a number of blogs/articles (here), sharing a StructureMap container across instances requires using a custom InstanceProvider, ServiceBehavior and ServiceHostFactory.
My initialization code looks like this. I do not use a config file.
var baseAddress = ConfigurationManager.AppSettings["BaseAddress"];
var port = Int32.Parse(ConfigurationManager.AppSettings["Port"]);
Host = new MyServiceHost(typeof(MediaFileServicePrivate), new Uri(string.Format(baseAddress, port)));
var binding = new NetTcpBinding();
Host.AddServiceEndpoint(typeof(IMediaFileServicePrivate), binding, string.Format(baseAddress, port));
How do I tell the service to use my custom service host factory? All the examples I can find configure it from the config file.
Is a ServiceHostFactory only used for IIS/WAS hosted scenarios? If so, how do I use SM for a self-hosted InstanceContextMode.Single service?
Has this not been answered? essentially you tell it to use your servicefactory in the wcf markup
<%# ServiceHost Language="C#" Debug="true" Service="WcfWithDI.Service1" CodeBehind="Service1.svc.cs" Factory="WcfWithDI.MyServiceFactory"%>
I have a sample project here all wired up with a custom provider (and structuremap)
https://github.com/billCreativeD/WCF_With_DI
Unfortunately it makes little sense to say "the service uses the factory". You would use the Ninject factory to create your service:
var factory = new NinjectServiceHostFactory();
var address = new Uri(_baseAddress, path);
ServiceHostBase host = factory.CreateServiceHost(typeName, new[] {address});
var binding = new NetTcpBinding();
host.AddServiceEndpoint(typeof(TheType), binding, string.Format(baseAddress, port));
The directive in the .svc file is used to tell .NET how to instantiate your service.

WCF: how to restrict using some protocols?

WCF (winodws service hosting) service uses set of protocols and bindings: http, https, net.tcp, net.pipe.
It uses config file settings.
I want to build demo version of the service.
This demo will use only net.pipe protocol.
How I can restrict service to use only this one?
I can do changes in code , but how and where?
ServiceHost owns collection of ChannelDispatchers in ChannelDispatchers property. You can use ChannelDispatcher.BindingName to figure out name of binding used in your service.
ServiceHost host = new ServiceHost(typeof(SomeService), baseAddress))
//configure service endpoints here
host.Open();
#if DEMO_MODE
foreach (ChannelDispatcher dispatcher in host.ChannelDispatchers)
{
//binding name includes namespace. Example - http://tempuri.org/:NetNamedPipeBinding
var bindingName = dispatcher.BindingName;
if (!(bindingName.EndsWith("NetNamedPipeBinding") || bindingName.EndsWith("MetadataExchangeHttpBinding")))
throw new ApplicationException("Only netNamedPipeBinding is supported in demo mode");
}
#endif

Performing action before WCF service is shutdown

I have a WCF service hosted in IIS7. The service has a static class with a static list containing strings (sort of log). It periodically write the entries to a file or db.
However when the IIS decides the recyle the app or terminate for whatever reason, the entries in the static field are lost.
Is there any way I can handle the service shuttingdown kind event and persist the data from memory?
Thanks
Shreedhar
I've implemented several services via IIS with a custom service host (originally I did this so I could implement IErrorHandler for global error handling).
You'll need two things - an implementation of ServiceHost and an implementation of ServiceHostFactory, which will call your custom service host. For example (just the relevant parts of code shown):
public class MyCustomServiceHost : ServiceHost
{
protected override void OnClosing()
{
// logic to save off your static data
base.OnClosing();
}
}
public class MyCustomServiceHostFactory : ServiceHostFactory
{
protected override ServiceHost CreateServiceHost(Type serviceType, Uri[] baseAddresses)
{
return new MyCustomServiceHost(serviceType, baseAddresses);
}
}
In your .svc file, you'd have something like this:
<%# ServiceHost Service="MyCompany.MyServiceName" Factory="MyCompany.MyCustomServiceHostFactory" %>
<%# Assembly Name="MyCustomServiceHost" %>
This is one way to do this (and this dates back to .NET 3.5 days); there are quite likely other ways to accomplish this, but at least this should give you some direction.

Problem creating WCF service with Windsor

Does anyone know how to configure WCF using Windsor on IIS 7.0? I'm using the latest from WCF Windsor facility trunk and Windsor 2.1.1. The example on http://www.castleproject.org/container/facilities/trunk/wcf/index.html is out of date. Even demo project in WCF facility doesn't mention how to setup WCF service in IIS using the config and I couldn't find any example where I can setup WCF on server side using system.serviceModel section of web.config or even through code. When I use the following code it always creates basicHttpBinding and I couldn't figure out how to setup different bindings.
protected void Application_Start(object sender, EventArgs e)
{
var returnFaults = new ServiceDebugBehavior
{
IncludeExceptionDetailInFaults = true,
HttpHelpPageEnabled = true
};
var metadata = new ServiceMetadataBehavior {HttpGetEnabled = true};
container = new WindsorContainer()
.AddFacility<WcfFacility>()
.Register(
Component.For<IServiceBehavior>().Instance(returnFaults),
Component.For<IServiceBehavior>().Instance(metadata),
Component.For<IMyService>()
.Named("MyService")
.ImplementedBy<MyService>()
.LifeStyle.Transient
);
}
And here is MyService.svc
<%# ServiceHost Language="C#" Debug="true" Service="MyService"
Factory="Castle.Facilities.WcfIntegration.DefaultServiceHostFactory, Castle.Facilities.WcfIntegration" %>
I recently wrote a blog post about Windsor's WCF Facility. Be sure to read the comments as well, as they include a discussion involving one of Windsor's active committers; they should give you a pretty good impression of the future direction.

How to do WCF Hosting in a console app?

How do I host my WCF class library in a console app? I have a WCF service within a class library and I wanted to test the service outside my project with a test app.(I have to do it outside the project)
Create a simple console app, add a reference to your WCF service assembly, and then basically write these few lines:
static void Main(string[] args)
{
using (ServiceHost host = new ServiceHost(typeof(Namespace.YourWCFService)))
{
host.Open();
Console.WriteLine("Service host running......");
foreach (ServiceEndpoint sep in host.Description.Endpoints)
{
Console.WriteLine(" endpoint {0} ({1})",
sep.Address, sep.Binding.Name);
}
Console.ReadLine();
host.Close();
}
}
All you do is instatiate a ServiceHost and pass it the type of a service (implementation) class, and then basically call .Open() on it.
The Console.ReadLine() just wait until someone presses ENTER and then terminates the service host.
That's all there is! (of course, you need to specify service address and bindings in a app.config for the service host console app for it to work)
You may create ServiceHost in your console application with your existing service contract (from your class library).
After the service is running, your test project can access your WCF Service as usual.
Consider using the WCF Service Host application: http://msdn.microsoft.com/en-us/library/bb552363.aspx
You can simply point the host to your service class library and configuration file and it will host your service for you.