What's the lifetime of an object using SignalR with Unity Dependency Resolver? - asp.net

Let me start with a little setup info... I am using the repository pattern and dependency injection via Unity. The repository is implemented via Linq-To-Sql. I inject my repositories into class constructors in my web project. The repositories have a PerWebRequest lifetime.
I have implemented a few SignalR hubs and have setup a Unity dependency resolver for SignalR. I'm injecting the same repositories into the hubs using the same Unity config file, which specifies these repositories are PerWebRequest also.
Now the punchline... I ran into a problem where the web project would update an Linq-To-Sql entity and the SignalR hub would read that entity and not get the updates. I have "solved" this problem by clearing the Linq-To-Sql cache before reading the entity in the SignalR hub; DataContact.Refresh() didn't update the entire object graph.
My DataContext for these repositories used in hubs are also PerWebRequest but it seams that the SignalR hubs are using a separate DataContext that does not get destroyed after the web request completes. It appears they are acting as singleton instances instead.
Do SignalR apps run in their own process and therefore my DataContext access from the hubs is a separate DataContext in that separate process?
How could the DataContext in the SignalR hub be instantiated with a PerWebRequest lifetime if it a separate process, apart from the web request lifecycle? Also, how does it seemingly act like a Singleton?

It's a while I don't use stuff like Linq2Sql or concepts like PerWebRequest, so I'm not 100% sure, but if I'm correct in saying that PerWebRequest is definitely tied to the lifetime of underlying HTTP requests, then those will hardly work with SignalR because its behavior can change a lot according to the chosen transport strategy. With WebSockets you might have several hub instantiations/method calls over the same connection, while with Long Polling you would probably have one (or zero) per HTTP request. Check here and here.
Given that the code you write with SignalR should be the same regardless of the transport, I think for hubs you'd always have to handle repositories in a specific way, maybe with an ad-hoc factory always clearing the cache each time a repository has to be supplied to a SignalR hub (you could try to be smart and check the transport strategy used, but those could be muddy waters).

Related

ServiceClient Caching Resutls

I am using ServiceClient to access data in dataverse from a c# application. The application is a worker service and the service client is injected into the application using dependency injection as a singleton. I am seeing the service client cache results. Is there a work around for this. If I update the record in dataverse my application continues to pull the old data.
It appears since my context was a singleton I needed to detatch any records that I may have already queried.

addScoped service lifetime in an ASP.NET Core multithreaded application

I know that AddSingleton() creates a single instance of the service when it is first requested and reuses that same instance in all the places where that service is needed.
If my ASP.NET Core application is multi-threaded, does that mean all HTTP requests from all users will share the same object instance created by dependency injection (DI)?
If so, that would be not a good way if the application process data to be stored. Are there any best practices?
As mentioned in Microsoft documentation, Service lifetimes, it depends on your specific case.
Presumably, if you have a service, A, and you want to create a new instance on every single request, you can use AddScoped() rather than AddSingleton(). A scoped lifetime service would be created per client request.
If for example, it was some shared data that possibly doesn't change between requests such as some values that are computed at application startup and reused throughout the lifetime of the application, then that is a usable scenario.

SignalR request pipeline, Hub lifetime

I am starting on signalR with asp.net webapi, and I am trying to understand the whole signalR request/connection pipeline and what is the lifetime of the hub and who creates and dispose the hub instance (does it gets created on every communication between client and server?)
One of the reason is that we need to understand how we should be using an IoC contain in signalR request scenario, how we control the lifetime of the dependency correct specifically the ISession or DBContext.
Hubs instances are created at every single request from a client. They are not kept around, therefore you should not put any state in them.
Hubs are created through a factory system which you can customize through its built-in dependency injection mechanism.

what is the best Session management opt ion for Asp.net mvc - wcf - BLL - Nhibernate repository

I have an application architecture which has following layers (or c# projects).
web front end (asp.net mvc2)
service layer (normal c# class library)
Model layer (normal c# class library with entities, service and repository Interfaces)
Data layer (implements repository interface defined in BLL and uses NHibernate)
ISession is opened per http request and its working fine.
Now, I would like to add wcf layer on top of my current service layer. wcf project plainly calls original service layer classes. But as soon as I do this, the session/session factory at asp.net becomes unusable/unavailable. Looks like, wcf is running in totally different context than asp.net. Hence I would like to move the logic of initinializing session factory and session management to wcf. How should I do it? and even before is it a good practice? one of the reason I would like to add wcf is because I want to expose the operations to other applications (which may not be http based).
Any help, blog post or book reference would be greatly appreciated.
Use Per-call instancing of NHibernate session. Check this article. It explains how to create attribute which will attach Session to current instance context.
you probably want to have WCF running in the same context as asp.net... try this article:
http://msdn.microsoft.com/en-us/library/aa702682.aspx

Creating/Exposing WCF services from an existing ASP.NET application

We need to expose some services (i.e. AddressValidatorService, CustomerFinderService) that currently reside in an ASP.NET application to other applications within our organization. Exposing these services via WCF seems like a natural fit, but I don't see any best-practices for how to pull these common services into a WCF wrapper in such a way that my existing ASP.NET application can continue to use them with minimal code changes and/or awareness that the service they are consuming is no longer in-process.
I'm especially looking for recommendations on how to structure the existing ASP.NET solution and whether to host our new WCF in the same solution or in some new shared WCF solution referenced by both our ASP.NET application and external callers.
Also, is it bad practice to simply promote the DTOs currently only consumed in-process via ASP.NET to full fledged data contracts or is it preferable to create duplicate DTOs that are explicitly decorated with [DataContract]? The latter seems like a maintenance nightmare.
To answer your second question:
Also, is it bad practice to simply promote the DTOs currently only consumed in-process via ASP.NET to full fledged data contracts or is it preferable to create duplicate DTOs that are explicitly decorated with [DataContract]? The latter seems like a maintenance nightmare.
It is considered a bad practice to expose your business model as WCF contracts. So if your DTOs are replicas of your domain model then it would be a strict no-no, because
1. any change in the model would directly effect the contracts and hence all the clients using it
2. you would be exposing your business "know-how" to the outside world.
The latter can tend to get difficult for any evolving system, but then you have various open source tools (like AutoMapper) that ease your mapping nighmares.
You can convert an existing project to WCF, then continue to use it in-process by using a project reference. It can then be consumed by an eternal source using the WCF client. A WCF client converts the class name from ClassName to ClassNameClient when consumed over WCF, but the class will function pretty much the same.
For example:
MyClass obj = new MyClass();
obj.DoSomething(withData);
Would become:
MyClassClient obj = new MyClassClient();
obj.DoSomething(withData);
You would publish the WCF project to some endpoint, like address.example.com, then use a service reference to the endpoint to reference the code, like a project reference, in your other projects.
Note that while the externally referencing projects would not be impacted by the change or know that the data is going over the network, if you have chatty calls to the project in question, it will definitely take a performance hit. You may want to consolidate related methods into single methods to save on round-tripping.
If these are exposed as static page services, there's no magic wrapper -- you're going to need to move code to a standalone service implementation class and put a .svc file in front of it. (Or use WCF4 fileless activation, or a service factory, but that's getting a bit away from the core question here.)
If these are exposed as ASMX, you can actually put an ASMX facade in front of a WCF service class and get basic HTTP/XML/ASMX responses as you would from your legacy ASMX webservices. You an expose that same WCF service class through standard WCF configuration for non-legacy consumers.
Finally, you can expose any WCF service as basicHTTP with serviceMetadata + httpGetEnabled, and you'll get a service endpoint usable by legacy consumers of an ASMX service.
http://msdn.microsoft.com/en-us/library/ms751433.aspx

Resources