views:

620

answers:

3

I'm working with an application which uses wcf and sharp architecture, I'm trying to create a service to write to the database. Here is my service:

[ServiceContract]
public interface IFacilitiesWcfService : ICloseableAndAbortable
{
    [OperationContract]
    void AddFacility(string facility);

}

[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
class FacilitiesWcfService:IFacilitiesWcfService
{
    public FacilitiesWcfService(IRepositoryWithTypedId<Facility,string> facilityRepository)
    {
        Check.Require(facilityRepository != null, "facilityRepository may not be null");

        this.facilityRepository = facilityRepository;
    }
    private readonly IRepositoryWithTypedId<Facility,string> facilityRepository;

    public void AddFacility(string facility)
    {
        facilityRepository.DbContext.BeginTransaction();

        Facility newFacility = new Facility();
        newFacility.SetAssignedIdTo(facility);
        newFacility.NAME=facility;
        newFacility.ADDRESS = facility;

        facilityRepository.DbContext.CommitTransaction();
    }
    public void Abort() { }

    public void Close() { }
}

And the LogisticsWCF.svc file in the web project:

<%@ ServiceHost Language="C#" Debug="true" Service="Project.Wcf.FacilitiesWcfService"
 Factory="SharpArch.Wcf.NHibernate.ServiceHostFactory, SharpArch.Wcf" %>

I created a client with svcutil.exe http://localhost:1905/LogisticsWCF.svc?wsdl and then created this test case:

[TestFixture]
class WCFLogisticsTests
{
    [Test]
    public void CanAddFacility()
    {

        FacilitiesWcfServiceClient facility = new FacilitiesWcfServiceClient();
        facility.AddFacility("NEW");
        facility.Close();
    }
}

But I get this exception:

TestCase 'Tests.Project.Web.WCFLogisticsTests.CanAddFacility'
failed: System.ServiceModel.FaultException`1[System.ServiceModel.ExceptionDetail] : The needed dependency of type FacilitiesWcfService could not be located with the ServiceLocator. You'll need to register it with the Common Service Locator (CSL) via your IoC's CSL adapter.

    Server stack trace:
    at System.ServiceModel.Channels.ServiceChannel.ThrowIfFaultUnderstood(Message reply, MessageFault fault, String action, MessageVersion version, FaultConverter faultConverter)
    at System.ServiceModel.Channels.ServiceChannel.HandleReply(ProxyOperationRuntime operation, ProxyRpc& rpc)
    at System.ServiceModel.Channels.ServiceChannel.Call(String action, Boolean oneway, ProxyOperationRuntime operation, Object[] ins, Object[] outs, TimeSpan timeout)
    at System.ServiceModel.Channels.ServiceChannel.Call(String action, Boolean oneway, ProxyOperationRuntime operation, Object[] ins, Object[] outs)
    at System.ServiceModel.Channels.ServiceChannelProxy.InvokeService(IMethodCallMessage methodCall, ProxyOperationRuntime operation)
    at System.ServiceModel.Channels.ServiceChannelProxy.Invoke(IMessage message)

    Exception rethrown at [0]:
    at System.Runtime.Remoting.Proxies.RealProxy.HandleReturnMessage(IMessage reqMsg, IMessage retMsg)
    at System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke(MessageData& msgData, Int32 type)
    at IFacilitiesWcfService.AddFacility(String facility)
    C:\Documents and Settings\epena\My Documents\SVN\Project\tests\Project.Tests\FacilitiesWcfService.cs(58,0): at FacilitiesWcfServiceClient.AddFacility(String facility)
    WCFLogisticsTests.cs(18,0): at Tests.Project.Web.WCFLogisticsTests.CanAddFacility()


0 passed, 1 failed, 0 skipped, took 4.52 seconds (NUnit 2.5.2).

I think I'm missing some configuration of sharp architecture, because when I don't use Factory="SharpArch.Wcf.NHibernate.ServiceHostFactory, SharpArch.Wcf" in the .svc file I don't get the exception, but I'm not able to write anything to the database ( I get an ISession not configured exception).

I tried to follow the Northwind example, but it's not working, What can I be missing?

+1  A: 

You're not returning anything from your service method, so it needs to be marked as IsOneWay=true:

[ServiceContract]
public interface IFacilitiesWcfService : ICloseableAndAbortable
{
    [OperationContract(IsOneWay=true)]
    void AddFacility(string facility);

}

By default, WCF expects request/response, i.e. it expects to get a response back from the service method. "void" doesn't count as a response - so just mark those service methods that don't return anything with the IsOneWay=true and you should be fine.

marc_s
Though this didn't resolve the issue, it's good to know. thank you
Leg10n
Feels like something WCF should be able to figure out on it's own. If it reads an attribute, why not read the return value as well? It's probably only done once on startup anyway.
Kristoffer
@Kristoffer: yes, I agree - seems WCF could just default to IsOneWay when the return value is "void" .... oh well....
marc_s
+2  A: 

Finally I've found the answer, I was missing the following line in the ComponentRegistrar:

container.AddComponent("facilityWcfService", typeof(FacilitiesWcfService));
Leg10n
Why not AddFacility?
Kristoffer
A: 

Can you please tell me where you added this line in your CompnentRegistrar as I am having the same issue, and cannot get it resolved.

Ryk