NullpointerException referrering service in Controller

Topics: Web Client Software Factory, User Forum
Mar 27, 2007 at 2:39 PM
I have a Web Client project generated from WCSF and I'm trying to call methods on my WCF-service.
The first time my Customer-view (I have created a BusinessModule called Customers) is rendered I call the WCF-service to first login, that is from the Controller. I can successfully login, and the page is rerendered.
Then, if I click a button in my View the variabel-instance of the WCF-service is null. And, of course, I get a NullReferenceException.

My WCF-service is registered in my ShellModuleInitializers method AddGlobalServices() like this:

globalServices.AddNew(typeof(MyServiceAgent), typeof(MyServiceAgent));


My question then:
How do I preserve the WCS-service-instance between postbacks? Is that I manually have to take care of or have I simply misunderstood the whole concept?

Fred
Mar 27, 2007 at 3:29 PM
Edited Mar 27, 2007 at 3:30 PM
Hello,

I'm not sure I understand your problem exactly, but here's a couple of thoughts:

Any page-level items that are created when a page request begins, eventually get torn down and destroyed at the conclusion of the request. This include all the items in PVC heirarchy, so you can't persist variables there.

The global services container however, is tucked away in the Application object and survives the duration of the entire Web Application life cycle. If you tuck a service away in the Global (or module) services CompositinContainers, you must fish it out (or better yet, have objectbuilder fish it out) the next time your PVC heirarchy is created.

So.. how do you accomplish this?

The easiest way to do this is to let ObjectBuilder do it for you. Remember, that any objects that are instantiated by ObjectBuilder (i.e. presenters and controllers) will automatically be decorated by any objects specified for dependancy injection:

public class mycontroller
{
private MyService _myService;
ServiceDependancy
public MyService _myService
{ ...
}
}

or, using the injection constructor method

public class mycontroller
{
private MyService _myServcie

public mycontroller(ServiceDependancy MyService myservice)
{
_myService = myservice
}


Now, when object buider builds your contoller, you'll have a handle to the instance of MyService that you put in memory when you registered it via the module initializer. Of course, this brings up a host of threading and member collission issues so be careful what you put in the service collection. but I digress...

It's important to note, that anything that isn't build by Object builder (i.e. some non module-initialized page like the Master page) won't be injection-enabled so you'd have to establish a connection to the CompositionContainers manually. There is a recent post about service dependencies in the master page that shows how to do this.

Please jump in here if I've mis-understood something, I'm still learning too :)

-r
Mar 28, 2007 at 8:22 AM
Thanks RSmallwood!

That made it for me. My silly fault was that I didn't set my service variable in the constructor like:

public myController(ServiceDependancy MyService myservice)
{
_myService = myservice;
}

You mention that when you use object builder to handle the service instances an give a host of threading and member collision issues. I have a service with a state (per session based), so will a new user logging in to my web application get the same instance of the service from object builder? I would like it to create a new instance of the web service of course....? Thats because my web service holds an instance of a COM-server that needs to my created per user with username/password etc.

Thanks again!

fred.
Mar 28, 2007 at 12:53 PM
Hey LF,

The thing to keep in mind is that services in the composition containers should be treated as singleton objects. In other words, they are shared (like a static class) across all HttpApplication Instances.

What I've done (and I hope I'm correct) is created a global service for these kinds of things that has a dependancy on the HttpLocator service that the factory provides (in the root composition container) Once you have a handle to the HttpContextLocator, you can use it to safely locate the current HttpContext object, then stick the reference to the COM object in the user's (Context) session bag.

Hope I haven't butchered that ;)

-r
Mar 28, 2007 at 1:28 PM
Ok. Thats okay, the butchering I mean ;-)
Well, I use the Web Service Software Factory with an Windows Communication Foundation service as my Web Service and that framework take care of all the state I need to use the same COM-object for a given session.
That mean I may have no use of Web Client SF, or more precisely the service-injection related functionality in the WCSF. What is your thoughts on that?

Anyway: thank you for your feedback and time. The bits are comming to place for me step by step now ;-)


Mar 30, 2007 at 3:17 AM
LF,

Not sure. I'm experimenting with it myself. I think the whole Idea of the the Composition Container idea is to give access to website-related resources that usually aren't available to non web projects. I think the point is that this enables a solution architecture that is free of the rigid constraints that IIS and ASP.Net put on the developer.

-r