When to Commit Unit Of Work using SignalR? - signalr

I'm trying to use the Unit Of Work pattern with RavenDb and SignalR. However, I can't find a clear SignalR Hub event to use as the hook to call SaveChanges on my RavenDb document session.
If it was MVC I'd use Application_EndRequest in Global.asax or OnActionExecuted in my Controller, but what equivalent is there for a SignalR Hub?

You could register a custom Hub pipeline module that overrides the HubPipelineModule.OnAfterIncoming method.
OnAfterIncoming will be called upon the completion of each Hub method.

Related

WCF Service + ASP .NET MVC application. Session expires after callback from the service

I have a following issue regarding using WCF service from my ASP .NET mvc application. Service requires a callback method to be implemented on the client side. For that I am using wsDualHttpBinding. Callbacks are being invoked and the correct info is recieved (checked using brakepoints multiple times).
The issue lies in the fact that I'm not able to save the data that I recieve when callback "SendComment" is invoked from WCF service. Callback method definition:
public void SendComment(ChatComment cc)
{
Session["Message"] = cc;
}
This is a method that should allow client (in asp .net) to recieve chat messages that are broadcasted to multiple clients from WCF service.
When I try to access Session["Message"] from the controller methods, it's value is null after I have recieved a callback. This is the main problem. I have to find a way to save the value for it to be available in current session context.
Additionally i can't access any of the other session variables I have saved right before the callback is invoked. They are always null.
Besides how do I know when I've recieved the callback? Do I have to use event handlers or somehow call the controller/view from this method?
I've already tried googling for the answer but none of the solutions explicitly state how to access the value after callback has happened.
P.S. Sessions are set to required in WCF Service.
This will not work the way you designed it. A few reasons why not:
You cannot access session from callback.
You cannot call client directly from ASP.Net MVC application.
You have too look for some other solution. I suggest you look into SignalR or if you need something simpler use DB to store data and pool from client.

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.

Invoking Spring MVC controller method from another thread (javax.jms.MessageListener)

I'm looking for a way of sending messages to my Spring MVC Controller from another thread. In particular my thread is an implementation of javax.jms.MessageListener which listens for messages on a ActiveMQ queue. As soon as I get a new message in the Queue, the jms MessageListener's onMessage() method is invoked. However, now I want to invoke another method in my spring controller whenever MessageListener's onMessage() is invoked.
The controllers in Spring MVC are not intended to be directly invoked the way you are looking for, but are designed to handle and respond to to web requests. A cleaner way to handle what you are doing will be to move the controller logic that you plan to invoke to a services layer and invoke this common services layer from controller and JMS listener.
If you absolutely want to, you can always autowire in a controller and invoke methods on it as if it is a normal POJO though.

How do I get a service to start from global.asax without having to invoke it?

I have a simple app where I use global.asax to map a serviceroute to a wcf service through a custom servicehostfactory in Application_Start. The constructor of that service does some initial processing to set up the service which takes a bit of time.
I need this constructor to fire when its serviceroute is added automatically. I tried creating a clientchannel from global.asax and making a dummy call to spin up the service, but discovered the service isn't up yet -- it seems application_start has to return?
So how do I get the constructor of the service to fire when first mapped through global.asax without having to manually hit the service? Unfortunately AppFabric isn't an option for us, so I can't just use it's built-in autostart..
UPDATE
I was asked for a bit more detail;
This is like a routing management service. So I have Service1 -- it gets added as a serviceroute in global.asax. Now I have http://localhost/Service1
Inside Service1 I have a method called 'addServiceRoute'. When called, it also registers a route for Service2. Now I have http://localhost/Service1/Service2.
My initial solution from global.asax was to build a channelfactory to http://localhost/service1 but that wouldn't work. Service1 wasn't up yet and wouldn't come up till Application_Start returned (Still not sure why?). So then I thought I'd cheat and move that initial addserviceroute call to the constructor of service1. Also didn't work.
It was mentioned that this shouldnt be in the constructor -- i agree, this is just testing code.
A singleton was also mentioned, which might be ok, but I intend to have more than one instance of Service1 on a machine (in the same app pool) so I don't think that'll work?
** UPDATE #2 **
I was asked for sample code.. here it is from global.asax (trimmed a bit for brevity).. So http://localhost/Test DOES come up.. But if I have to use appfabric to warm up Test and get its constructor to fire, then don't I need Test.svc or something? How do I get appfabric to even see this service exists?
protected void Application_Start(object sender, EventArgs e)
{
RouteTable.Routes.Ignore("{resource}.axd/{*pathInfo}");
RouteTable.Routes.Add(
new ServiceRoute("Test", new MyServiceHostFactory(ITestService, BindingType.BasicHttpBinding, true), TestService));
}
What you describe requires singleton service (something you should avoid) because normally each call or session gets a new instance = a new call to constructor. In self hosted WCF service you can instantiate singleton service instance and pass it to ServiceHost constructor. In case of IIS hosted service used together with ServiceRoute you can try to create your own class derived from ServiceHostFactory and pass created service instance as a parameter to its constructor. In this factory class implement CreateServiceHost method and pass that existing service instance into ServiceHost constructor. To make this work your service class must still be handled as singleton through service behavior.
Btw. constructor should not do any time consuming operation. Constructor is for constructing object not for initializing infrastructure. Using constructor for such initialization is bad practice in the first place.
AppFabric autostart is what I would recommend - even though you say you cannot use it - this is the problem it was meant to solve (warming up your service).
As an alternative before AppFabric existed, you would have to use a scheduled task (a.k.a cron job) with an executable that calls into the service you want initialized. The way AppFabric autostart works is by using named pipes (net.pipe) to trigger the warm up - but it just does this exact thing when the service is recycled. The difference between the scheduled task approach and the AppFabric autostart is that the scheduled task doesn't know when your application pool has been recycled - you would need to poll your service periodically to keep it warm.
Alternatively you could consider hosting your WCF application outside of IIS via self-hosting. This would avoid the warm-up issue, but you wouldn't achieve many of the benefits of the IIS hosted container. See HttpSelfHostServer in the new MVC Web API or review using a standard ServiceHost.

Unity to dispose of object

Is there a way to make Unity dispose property-injected objects as part of the Teardown?
The background is that I am working on an application that uses ASP.NET MVC 2, Unity and WCF. We have written our own MVC controller factory that uses unity to instantiate the controller and WCF proxies are injected using the [Dependency] attribute on public properties of the controller. At the end of the page life cycle the ReleaseController method of the controller factory is called and we call IUnityContainer.Teardown(theMvcController). At that point the controller is disposed as expected but I also need to dispose the injected wcf-proxies. (Actually I need to call Close and/or Abort on them and not Dispose but that is a later problem.)
I could of course override the controllers' Dispose methods and clean up the proxies there, but I don't want the controllers to have to know about the lifecycles of the injected interfaces or even that they refer to WCF proxies.
If I need to write code myself for this - what would be the best extension point? I'd appreciate any pointer.
I've created a unity extension that will take care of disposing instances created by the container on TearDown.
See http://www.neovolve.com/2010/06/18/unity-extension-for-disposing-build-trees-on-teardown/
A possible workaround is that you could also write a wrapper around your proxies that will on dispose (called by Unity when disposing instances) call a Close method of the proxy. Is that a viable scenarion for you ?
Once you've got your UnityDependencyResolver
GlobalConfiguration.Configuration.DependencyResolver = new UnityDependencyResolver(container);
You can then call Dispose on the resolver. In ASP.NET you might choose to call this from your Global.asax.cs Application_End method like this:
GlobalConfiguration.Configuration.DependencyResolver.Dispose();
This will then call dispose on all the stuff that have container lifetime, such as instances added to the container with:
var myFooInstance = new Foo();
container.RegisterInstance<IFoo>(myFooInstance);

Resources