I have the following scenario:
I am using castle windsor component activator to create and destroy the scope for the WCF.
I have a WCFServiceActivator that extends Castles DefaultcomponentActivator and implements the InternalCreate and InternalDestroy to call BeginScope and Scope.Dispose() for the service.
WCF session is defined as per request
I implemented a ErrorHandler class and defined the ProvideFault and HandleError
In the handle error I want to send exception metrics to ApplicationInsights, but when I use castle to provide some factory I get no scope, since it was already destroyed after the provide value runs and the response is sent to the client.
Basically when the HandleError method executes, the scope created by the activator was already destroyed due to the perWcfRequestLifecycle.
I was wondering on maybe creating a new Castle LifecycleStyle that wraps a higher layer of the wcf but I don't know if it is possible.
Does someone have a solution for this scope issue?
Related
I want to change scope of service instance scope from Singleton to Transient(where it create instance every request) using service url but getting compile time error
Below is working code without service url
services.AddTransient(typeof(IUser), typeof(My.UserService));
Below is singleton scope with service url
services.AddSingleton(typeof(IUser), ServiceProxy.Create<IUser>(new Uri("fabric:/My.Microservices/MY.UserService")));
Now I want to add scope as Transient using service url like singleton, how?
Use the generic approach for registering your service, along with a factory delegate
services.AddTransient<IUser>(sp =>
ServiceProxy.Create<IUser>(new Uri("fabric:/My.Microservices/MY.UserService"))
);
In the above code, every time IUser is resolved the delegate will be invoked.
I have a class that is exposed as a WCF service. The class lifetime is managed by Castle Windsor, which attaches a number of interceptors like logging aspect and permission aspect. With WCF I can pass some additional data in message headers, like the username or a userSessionId. Then on the server side the Permission interceptor can use OperationContext.Current.IncomingMessageHeaders and read which user is making the call. Then it can allow the invocation to proceed or throw an exception.
The problem is that now I want to ditch WCF and replace it with something else (RabbitMQ to be excact). How can I get a similar functionality to WCF OperationContext.Current, but without WCF? Or otherwise add some additional data to an IInvocation, so the interceptor would be able to read? The interceptor must be transparent to the rest of the world as usual.
In Simple Injector documentation is sentence: "A new instance of the service type will be created for each request (both for calls to GetInstance and instances as part of an object graph).".
I'm little bit confused, what request means? - Is it request like http request or it is request to resolve service (instance) from container?
In part of singleton is term lifetime; lifetime is defined by container.Options.DefaultScopedLifestyle = new WebApiRequestLifestyle();?
By default Transient is used which means every time you request the type a new instance will be created.
You can also use Web Request if you want to reuse the instance for the whole web request.
http://simpleinjector.readthedocs.org/en/latest/lifetimes.html#perwebrequest
I read this Article and I thought I write a little ping Service (Both Service and Client can ping).
however, when I use
[ServiceBehavior(InstanceContextMode=InstanceContextMode.PerSession,
ConcurrencyMode = ConcurrencyMode.Multiple)]
My ping service only creates one instance. But I want multiple instances. My callback interface is saved in a private but it is overwritten because when the clients register, they register to one instance and not different.
Is that Bad design in my case or why does wcf only create one instance?
The problem was with the Windsor Container.
When I instanciate a Component with ´.AsWcfService´ Windsor doesn't care about the ServiceBehavior. So I need to set the lifestile to transient for this case.
In my Managed Application, I currently have my WCF services running as:
SomeService service = new SomeService(container) //IUnityContainer
ServiceHost serviceHost = new ServiceHost(service, serviceAddress);
Whats the catch ? SomeService defined with:
[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single
This is not good anymore, I need to make it InstanceContextMode.PerCall.
When trying to .Open() If changing the InstanceContextMode to "PerCall" - it will throw:
System.InvalidOperationException: In order to use one of the ServiceHost constructors that takes a service instance, the InstanceContextMode of the service must be set to InstanceContextMode.Single. This can be configured via the ServiceBehaviorAttribute. Otherwise, please consider using the ServiceHost constructors that take a Type argument
Is this the solution to my problem ? How do I pass values to the constructor on my wcf service?
My Main concern:
I run different types of services inside this managed application, It seems that this solution is good only if i run one type of service.
When more than one service instance will be needed (PerCall or PerSession) then passing a single service instance into the ServiceHost isn’t enough... which is the exception.
Controlling instance creation is managed by the IInstanceProvider.
Is this the solution to my problem ? How do I pass values to the constructor on my wcf service?
This only answers half your question. You are using Unity. The management of creating the container needs to be part of the implementation. The most common solution is to use Unity.WCF which is also available as a NuGet package.
Note that Unity.WCF doesn’t support object lifetimes based WCF OperationContexts. There are multiple (more complicated) implementations like this that do.