Interfacing Service using WCF which has [ServiceDependency]. Getting null references

Topics: Web Client Software Factory, User Forum
Oct 22, 2007 at 1:52 PM
Edited Oct 22, 2007 at 2:04 PM
Hi all, I'm using the WCSF for a project, and as part of the proposed architecture, I'm creating services that will be consumed by the controller. For example I have a Customer Business Module, the dependency injection chain looks something like this:

Customer.aspx.cs -> CustomerPresenter -> CustomerController -> CustomerService -> CustomerDaoService

Here the view creates the presenter using the [CreateNew], the presenter has the controller injected, the controller uses the [ServiceDependency] to have access to the CustomerService, and the CustomerService again uses the [ServiceDependency] to have injected the dependency of the CustomerDaoService. the [ServiceDependency] work because in the InitialiseModule class, I've added both services to the service list. up to here it's a-ok.

Now what I wish to do is to expose the CustomerService using a WCF Web Service. My problem is that if I do something like this:

WCF Interface Implementation (Hard Reference)-> CustomerService (still using [ServiceDependency]) -> CustomerDaoService

In the CustomerService the CustomerDaoService will be null. I know this will be null because OB uses a httpmodule to create this container. My question is:

Is there a way I can reuse CustomerService using an WCF interface having all the dependencies properly injected?

I think that to get this to work some how, the project which has the WCF Interface Implementation, has to have the composite httpmodule, which has to initialise the Customer Module, which in it's Module Initialiser the CustomerService and the CustomerDaoService are added to the service list, and in the WCF Interface Implementation have a [CreateNew] for the CustomerService (kinda like the code behind does with the CustomerPresenter in this example). I had a go at this, but no dice (but if this is the right direction, I would appreciate some tips/gotchas to get this working).

The Both RI I've seen get around this sticky issue by just having this:
WCF Interface Implementation (Hard Reference)-> CustomerService

But in reality the service should be allowed to have services injected. Any ideas on how to get his to work?

Thanks for any help/ideas/clues before hand.
Developer
Oct 22, 2007 at 10:08 PM
For the dependencies of a class to be injected, the object should be built with ObjectBuilder.
In this case, CustomerService is a WCF Web Service, and ASP.Net is responsible for the creation of an instance of the service. Therefore none service dependencies will be injected.
The Responsive Composite Web Client Reference Implementation use the following code to make this possible in all its asmx services.

// Contructor.
public CustomerService()
{
    WebClientApplication.BuildItemWithCurrentContext(this);
}
The BuildItemWithCurrentContext method of the WebClientApplication class is in the new version of Composite Web Client Library.
I recommend you to read the following article to have a deeper knowledge about the BuildItemWithCurrentContext method: Composite Web Application Block Gets MasterPage, Page and UserControl Base Classes to Hide Dependency Injection.

Please let me know if this helps.

Mariano Converti
http://staff.southworks.net/blogs/mconverti/
Oct 25, 2007 at 7:56 AM
Hi Mariano,

Thanks for the advice. I took a bit of head banging to get it to work though, the RI used a asmx service, but I'm using WCF. So the trick is to set aspNet Compatibility to true, like so:

<system.serviceModel>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" />
</system.serviceModel>

and set your service implementation to have this attribute:
[AspNetCompatibilityRequirements
(RequirementsMode = AspNetCompatibilityRequirementsMode.Required)]

It was easier to start from a WCSF WAP project, and add your WCF endpoint definition there. Another small trick is to add the service to the global services.

Just one comment and it's that I didn't like to enable aspnet compatibility, It would be good if the container wasn't dependant on this fact.

Thanks,
Carlos
Oct 27, 2007 at 9:56 AM
Hi Carlos

Thanks fro your feedback. We did look into the possbility of using DI on a WCF Service. CWAB originally was not designed for this. Services in CWAB sit in the Composition Container that is accessed through the HTTPContext. In a WCF service the HTTPContext is only available if it is exposed as an ASMX. Fixing this would have been a significant effort that would have impacted other work that was higher priority. If you are interested in a pure DI container, you could check out the CodePlex Container or the many other alternatives such as Windsor.