Castle wcf facility lifestyle - perwcfoperation not recreating new instances - wcf

I'm using Castle windsor wcf facility to self host my services. Am hosting through windows service.
Am using below code for registering my services -
container.Register(
Classes
.FromThisAssembly()
.Pick()
.If(x => x.IsClass && HasServiceContract(x))
.WithServiceDefaultInterfaces()
.LifestylePerWcfOperation()
.Configure(c => c.AsWcfService()));
I have listed all the endpoints in the app.config file and it will host them using net.tcp binding.
Problem am facing is, even though lifestyle is set as perWcfOperation, a new instance of the XXservice is not getting created per operation. Am assuming that "perWcfOperation" is exactly similar to "InstanceMode.PerCall" in Wcf. If that is the case then why a new object instances are not created for every call?
Any thoughts?
Thanks
Sai

Related

Need to understand the concept from a book

I am learning WCF using a book named "Window communication foundation 4: step by step". I the second chapter, there was a tutorial about developing windows service for WCF. The client communicates to the named pipe endpoint.
//WCF inside Windows service.
protected override void OnStart(string[] args)
{
productsServiceHost = new ServiceHost(typeof(ProductsServiceImpl));
NetNamedPipeBinding binding = new NetNamedPipeBinding();
productsServiceHost.AddServiceEndpoint(typeof(IProductsService),
binding, "net.pipe://localhost/ProductsServicePipe");
productsServiceHost.Open();
}
And the client has an endpoint defined in App.config
<endpoint address="net.pipe://localhost/ProductsServicePipe"
binding="netNamedPipeBinding" bindingConfiguration=""
contract="ProductsService.IProductsService"
name="NetNamedPipeBinding_IProductsService" />
I need to create a proxy object to a "Service reference" which is not the windows service I mentioned earlier.
// Create a proxy object and connect to the service
// There service reference for "ProductsServiceClient" is
// "http://localhost:51397/ProductsService/Service.svc"
ProductsServiceClient proxy = new ProductsServiceClient("NetNamedPipeBinding_IProductsService");
Without "ProductsServiceClient", I could not initiate the proxy. Why do I need to that service reference, as I connect to a window service. I could not understand the concept clearly.
In this case the term service is being used in two senses. You have the windows service which is the host for the WCF service. The reason that you had to create a service reference was so that your project could generate all off the code necessary to create a proxy to communicate with the WCF service. As an alternative to adding a service reference you could also have used a Channel Factory. The key thing to understand is that when you are creating a WCF service you generally access that service through the WCF pipeline (via a proxy or a channel factory), even if you are doing so from the project where it is defined.
If it is the case that you are unclear about how to generate a proxy for self hosted WCF service, you should look into how svcutil.exe can used to generate proxies for compiled services.

Create WCF Service to be hosted differently

I have a WCF service which programmatically creates its endpoints rather than using a config file - I'm looking into this as our field engineers are prone to break XML easily and we may use different types of binding in different scenarios.
This works well in self-hosted environments (console app, windows app) and as a Windows Service.
Can I do this with a service in IIS or do I have to provide a .SVC file for each endpoint ?
Also will the endpoint address from the client end have to include the .SVC extension ?
This is not a service intended to be used by third parties, only by our client components. We may expose parts of our API later but not initially.
If you're using .NET Framework 4.0 (and later), you can use the ASP.NET routing integration to define a service using a custom ServiceHostFactory implementation. A few things you'll need:
In web.config, set the attribute aspNetCompatibilityEnabled on the <system.serviceModel / serviceHostingEnvironment> element to true
Add a global.asax / global.asax.cs file, and in the Application_Start add a new ServiceRoute to the ASP.NET RouteTable.Routes collection. The service route requres you to define a new service host factory, where you can define your endpoints programmatically.
With that you'll be able to have endpoints without the ".svc" in their addresses. You can also use the service host factory without using routes, by creating a .svc file for each service (not endpoint), and using the Factory attribute in the <%# ServiceHost directive.
For more information about service host factories, check the post at http://blogs.msdn.com/b/carlosfigueira/archive/2011/06/14/wcf-extensibility-servicehostfactory.aspx.

Ninject Di bindings using a WCF service

I recently created a WCF service library. I am planning on hosting it in IIS. Since I want to reuse my repository layer I decided to go use Ninject in my WCF service as well (I use it in other projects in the solution).
I installed the Ninject Wcf Extensions. I configured it using the NinjectServiceHostFactory in the svc file. I added a Global.asax file to override the CreateKernel() that inherits from NinjectWcfApplication but I am not sure if I am using the bindings correctly. I first started with:
Bind<IUnitOfWork>().To<UnitOfWork>().InRequestScope();
But I quickly realized that this does not work since no data was saved to my database. It appears that the WCF service does not use the ASP.NET pipeline. I went ahead and tried both of these as well just to see if my data was committed to the database:
Bind<IUnitOfWork>().To<UnitOfWork>().InThreadScope();
Bind<IUnitOfWork>().To<UnitOfWork>().InTransientScope();
No luck. I then decided to try:
Bind<IUnitOfWork>().To<UnitOfWork>().InSingletonScope();
This worked but I don't want my database context to be shared by every single request that comes in to the WCF service. I then did some research and found the following approach:
Bind<IUnitOfWork>().To<UnitOfWork>().InScope(c => OperationContext.Current);
This works but is it correct? I wan t something to resemble the InRequestScope for a MVC application. Each request to the service should get its own Database context.
I suggest to have a look at the latest build from the CI-Server http://teamcity.codebetter.com
You need Ninject, Ninject.Web.Common, Ninject.Extensions.Wcf
With this version you can use InRequestScope for Wcf.
I am new to Ninject, but I can tell you that OperationContext.Current is the equivalent to HttpContext.Current for web application.
So your first thought was to use .InRequestScope(); (which is equivalent to .InScope(c => HttpContext.Current);)
so I guess that using .InScope(c => OperationContext.Current); for WCF is pretty correct.

WCF PerSession service and AutoMapper

where should I put the code for configuring AutoMapper mapping between DTO and EntityFramework Entities for WCF PerSession services?
If in the default constructor, does that mean every session will create an individual mapping and causes lots of overhead on the server side?
Thanks
Configuration of AutoMapper is global for the whole application so your service should not do any configuration itself. AutoMapper should be configured in your application bootstraper (when the application starts). For example in WCF service hosted in IIS (over HTTP) you can use standard Global.asax and Application_Start.

accessing WCF service through URL

I have a WCF service ( Let's say WCFService1 ) is deployed on two remote machines. Since the same service is deployed on two different machines they have common interface and common methods exposed.
WCFService1 is deployed on Machine1 and Machine2.
To consume WCF service from client machine, I have created a client app:
I have added a design time reference of WCF service (WCFService1 )( with the help of URL http://11.12.25.23/WCFService/Service1.svc).
Now I can invoke the methods exposed in the service. Up until now its fine...
Now my question is If I have to update client at run time with same service hosted in different machine with different URL ( Let's say http://12.12.24.24/WCFService/Service1.svc), How can I do that?
At present I am doing this:
BasicHttpBinding binding = new BasicHttpBinding();
EndpointAddress address = new EndpointAddress("http://12.12.24.24/WCFService/Service1.svc");
MyServiceClient serviceClient = new MyServiceClient(binding, address);
but whenever I use to invoke the method exposed in the service I got binding mis match error.
Have you tried invoking your client first?
eg:
MyWCFClient client = new MyWCFClient();
client.EndPoint.Address = new EndpointAddress("http://somewhere:888/here.svc");
I'd suspect, that if you look in your web.config file on Machine1, you'll see that the binding there is WSHttpBinding (or something different than BasicHttpBinding). If you change it to BasicHttpBinding (assuming that is what you really want), you'll remove this error.
How is your service configured? Show us your server-side and client-side config!
Binding mismatch means you're either not using the same binding, or some vital parameter on the binding is different - there must be something configured wrong - so show us the config!
Marc