Self Hosted WCF via MSMQ Simple Injector Lifestyle - vb.net

I'm using WCF (self-hosted) using MSMQ bindings and wanted to use the Per WCF request lifestyle with SimpleInjector. I setup my code as:
Dim httpLifecycle = New SimpleInjector.Integration.Wcf.WcfOperationLifestyle(True)
container.Register(of ISomeType, SomeType)(httpLifecycle)
Over MSMQ, this doesn't work, as I get the error:
The dependency resolver for the web services host failed to
initialize: SimpleInjector.ActivationException: The registered
delegate for type ILoader threw an exception. The ISomeType is
registered as 'WCF Operation' lifestyle, but the instance is requested
outside the context of a WCF Operation.
Is there a way the WCF request lifestyle an work with MSMQ?

I ended up using a per execution scope and defining that scope within the WCF service operation itself. By scoping it that way, it ensured the dependencies opened and closed when I wanted them to.
I needed to include execution context scoping.

Related

Background tasks with .NET CORE Lifetime and DI injection

I want to use background tasks in asp.net core.
I found helpful documentation https://learn.microsoft.com/en-us/aspnet/core/fundamentals/host/hosted-services?view=aspnetcore-6.0&tabs=visual-studio
I wonder why their lifetime apparently is scoped: Hosted service that activates a scoped service. The scoped service can use dependency injection (DI).
What is a scope in this context?
For web applications, a scoped lifetime indicates that services are created once per client request (connection). Register scoped services with AddScoped.
In apps that process requests, scoped services are disposed at the end of the request.
While I do understand what that means for e.g a standard http get request to an api,
I do not understand the meaning for a background worker.
Imho it would make more sense to have a singleton backgroundworker. I certainly do not want to have multiple instances running at a time in my application.
Another thing is DI in background workers which apparently differs fron standard services:
To use scoped services within a BackgroundService, create a scope. No scope is created for a hosted service by default.
I cannot confirm that:
services.AddHostedService(x => new DataPersister(x.GetRequiredService<IAsyncDocumentSession>(), x.GetRequiredService<ILogger>()));
seems to work just fine.
You have to read the sentence “Hosted service that activates a scoped service” within its full context:
This article provides three hosted service examples:
Background task that runs on a timer.
Hosted service that activates a scoped service. The scoped service can use dependency injection (DI).
Queued background tasks that run sequentially.
(from “Background tasks with hosted services”, emphasis mine)
So it is not the case that hosted services have a scoped lifetime. All hosted services added using AddHostedService() are actually added with a singleton lifetime, ensuring that there will only ever be a single instance of it.
What the article refers to is the situation when you need to consume a scoped service, like a database connection, within a hosted service. Since you cannot inject scoped dependencies into a singleton service, you will need a different solution there. And the solution usually involves having the singleton service (the hosted service in this case) create a service scope itself from which it can then retrieve the scoped dependency.
I went into more details about the service scopes in this recent answer to a similar question if you are interested.

WCFBinding in DotCMIS

Am trying to invoke a CMIS repository webservice URL from a WCF service. I need to ensure that I have WCF binding (basicHttp) on invoking that webservice (to mutually exchange certificates between client and Data power). Hence i used the below code:
DotCMIS - Code Snippet:
Parameters[SessionParametet.WebServicesWCFBinding] = "myWCFServiceBindingName";
Note: "myWCFServiceBindingName" is the name of basicHttpBinding defined in the web.config related to the WCF service.
There is no error when the above code is executed but it throws the below error message when instantiating a session to perform operations on the repository.
Error Message:
No elements matching the key 'myWCFServiceBindingName' were found in the configuration element collection.
Could someone share your thoughts on this issue ?

WCF in UWP: should I explicitly call the OpenAsync() of the service client(proxy)?

I'm developing a UWP client project which need to consume some services of a WCF server. I uses the "add service reference" tool of Visual Studio to auto generate service clients(proxies). The binding type is NetTcpBinding. Below is some code snippet which create the service client:
NetTcpBinding tcpBinding = new NetTcpBinding();
tcpBinding.Security.Mode = SecurityMode.None;
tcpBinding.Security.Transport.ClientCredentialType = TcpClientCredentialType.None;
tcpBinding.Security.Message.ClientCredentialType = MessageCredentialType.None;
MainServiceClient = new MainServiceClient(tcpBinding, new EndpointAddress("net.tcp://localhost:8773/MyWCF/MainService/tcp"));
The question is do I need to call OpenAsync() method of MainServiceClient? It seems the service client can be auto opened when it is first called. But I read from this article that auto-opened service client would have some performance penalty. The article was written in 2007. I just wonder if this mechanism have changed today, especially in UWP project. Can anyone share more light on this topic? Thanks!
To explain this case, you should know three ways to do WCF instance management. WCF has provided three ways by which you can control WCF service instances:Per call, Per session, Single instance.
When we configure a WCF service as per call, new service instances are created for every method call you make via a WCF proxy client.
Very often we need to maintain state between method calls or for a particular session. For those kinds of scenarios, we will need to configure the service per session. In per session, only one instance of a WCF service object is created for a session interaction.
Often we would like to create one global WCF instance for all WCF clients. To create a single instance of a WCF service, we need to configure the WCF service as Single instance mode.
And there are three ways by which you can handle concurrency for each service instance in WCF :single, multiple, and reentrant.
Single: A single request has access to the WCF service object at a given moment of time. So only one request will be processed at any given moment of time. The other requests have to wait until the request processed by the WCF service is completed.
Multiple: In this scenario, multiple requests can be handled by the WCF service object at any given moment of time. In other words, requests are processed at the same time by spawning multiple threads on the WCF server object. So you have great throughput here but you need to ensure concurrency issues related to WCF server objects.
Reentrant: A single request thread has access to the WCF service object, but the thread can exit the WCF service to call another WCF service or can also call a WCF client through callback and reenter without deadlock.
In "Instance mode = Per Session and Concurrency = Single" combination, one WCF service instance is created for every WCF client session because the WCF instance mode is set to per session. All the method are executed in a sequential manner one by one. In other words, only one thread is available for all method calls for a particular service instance.
For the above scenario, you should always open WCF client proxy explicitly before you are making any calls. Because it will maintain service state between method calls and obtain high performance.
For more detail you could refer to "WCF Concurrency (Single, Multiple, and Reentrant) and Throttling" and "Three ways to do WCF instance management".

WCF - StructureMap - Caching objects for the duration of the request only

So I already have a working implementation of StructureMap with the WCF service (including custom instance provider, behaviors, etc.)
When I try to have an object that is instantiated only once per user request, I use the InstanceScope.HttpContext and it throws because the context is null.
Do anyone have a proper way of doing that?
On the server-side of the WCF service? By default, WCF has nothing to do with ASP.NET and thus all your HttpContext etc. aren't there.
By default, your WCF services will be called on a "per-call" basis, e.g. each request gets a brand-new, separate, totally isolated instance of your service class. Why not just put those things into the service class as internal fields??
Or you might want to check out this blog post on how to abstract request state and providing sample implementations for ASP.NET (using HttpContext.Items) and WCF.

WCF PerCall instance server and Dependency Injection using Prism?

If I have a client/server type of application built using both Prism and WCF, and I would like on the serverside to have the wcf service to be instatiated per call BUT I would like to use dependency injection (using the UnityContainer in Prism). How could I possibly do this? Should I have a single instance service it would be no problem, but are there any hooks in WCF to allow for a delegate to be called whenever a service is supposed to be instantiated and have this instance returned?
Any ideas?
Cheers!
It is possible! WCF provides a plugin to the WCF responsibility chain called an IInstanceProvider. This allows for you to replace the construction with your own.
Someone has implemented this as a service behavior and is available here:
http://code.msdn.microsoft.com/WCFResources/Release/ProjectReleases.aspx?ReleaseId=1252