0

The company I work for has a CRM app which you can only access programmatically from their SDK. The SDK has a Framework object which has a LogOn() method.

I have a WCF Service which is hosted in a Windows Service.

When the Windows Service starts it will instantiate the Framework object and run LogOn(). If this is successful it starts the WCF Service.

The methods in the WCF Service need to be able to access the Framework object in order to perform the tasks I want.

Where the Framework object is in the Windows Service:

// Start the Windows service.
    protected override void OnStart(string[] args)
    {
        actFwk = new ActFramework();

        if (logIntoACT())
        {
            if (serviceHost != null)
            {
                serviceHost.Close();
            }

            // Create a ServiceHost for the ACTWcfSvc type and 
            // provide the base address.
            serviceHost = new ServiceHost(typeof(ACTWcfSvc));

            // Open the ServiceHostBase to create listeners and start 
            // listening for messages.
            serviceHost.Open();
        }
        else
        {
            if (actFwk.IsLoggedOn)
                actFwk.LogOff();

            this.Stop();
        }
    }

Where I want to access the object:

public class ACTWcfSvc : IACTWcfSvc
{
}

How do I access the Framework object from the WCF Service? Do I pass it into the ServiceHost? Do I do this in the constructor of ACTWcfSvc?

EDIT:

Following the link CodeCaster gave me I was able to solve my problem. How do I pass values to the constructor on my wcf service?

Here is how it got it working:

In the OnStart() method of the Windows Service task I used

serviceHost = new MyServiceHost(actFwk, typeof(ACTWcfSvc));

I defined these classes as listed in the link and replaced "IDependency dep" with "ActFramework actFwkDep":

public class MyServiceHostFactory : ServiceHostFactory
{
    private readonly ActFramework actFwkDep;

    public MyServiceHostFactory(ActFramework actFwk)
    {
        this.actFwkDep = actFwk;
    }

    protected override ServiceHost CreateServiceHost(Type serviceType,
        Uri[] baseAddresses)
    {
        return new MyServiceHost(this.actFwkDep, serviceType, baseAddresses);
    }
}

public class MyServiceHost : ServiceHost
{
    public MyServiceHost(ActFramework actFwkDep, Type serviceType, params Uri[] baseAddresses)
        : base(serviceType, baseAddresses)
    {
        if (actFwkDep == null)
        {
            throw new ArgumentNullException("actFwkDep");
        }

        foreach (var cd in this.ImplementedContracts.Values)
        {
            cd.Behaviors.Add(new MyInstanceProvider(actFwkDep));
        }
    }
}

public class MyInstanceProvider : IInstanceProvider, IContractBehavior
{
    private readonly ActFramework actFwkDep;

    public MyInstanceProvider(ActFramework actFwkDep)
    {
        if (actFwkDep == null)
        {
            throw new ArgumentNullException("actFwkDep");
        }

        this.actFwkDep = actFwkDep;
    }

    #region IInstanceProvider Members

    public object GetInstance(InstanceContext instanceContext, System.ServiceModel.Channels.Message message)
    {
        return this.GetInstance(instanceContext);
    }

    public object GetInstance(InstanceContext instanceContext)
    {
        return new ACTWcfSvc(this.actFwkDep);
    }

    public void ReleaseInstance(InstanceContext instanceContext, object instance)
    {
        var disposable = instance as IDisposable;
        if (disposable != null)
        {
            disposable.Dispose();
        }
    }

    #endregion

    #region IContractBehavior Members

    public void AddBindingParameters(ContractDescription contractDescription, ServiceEndpoint endpoint, BindingParameterCollection bindingParameters)
    {
    }

    public void ApplyClientBehavior(ContractDescription contractDescription, ServiceEndpoint endpoint, ClientRuntime clientRuntime)
    {
    }

    public void ApplyDispatchBehavior(ContractDescription contractDescription, ServiceEndpoint endpoint, DispatchRuntime dispatchRuntime)
    {
        dispatchRuntime.InstanceProvider = this;
    }

    public void Validate(ContractDescription contractDescription, ServiceEndpoint endpoint)
    {
    }

    #endregion
}

In my WCF Service constructor I added:

 public class ACTWcfSvc : IACTWcfSvc
{
    ActFramework actFwk;

    public ACTWcfSvc(ActFramework actFwk)
    {
        this.actFwk = actFwk;
    }

    public string GetCurrentActUser()
    {
        return actFwk.CurrentUser.UserLogOn;
    }
}

And in the service interface I have:

// Define a service contract.
[ServiceContract(Namespace = "http://ACTWcfService")]
public interface IACTWcfSvc
{
    [OperationContract]
    string GetCurrentActUser();
}

Now in a client program I can run the GetACTCurrentUser() method and it returns the username of the current user as I wanted.

Hopefully this will help someone understand a bit more how to do this.

Community
  • 1
  • 1
e_hoog
  • 37
  • 4
  • By providing an instance to "the Framework object" to "the WCF Service". It's a bit unclear what exactly the problem is. Show relevant code. – CodeCaster Mar 06 '15 at 16:00
  • See [How do I pass values to the constructor on my wcf service?](http://stackoverflow.com/questions/2454850/how-do-i-pass-values-to-the-constructor-on-my-wcf-service). You can also make it single-instance and pass the instance to the `ServiceHost` constructor. – CodeCaster Mar 06 '15 at 16:12
  • I've edited my post I hope it makes it more clear. I am sure this is something extremely basic which I am just not grasping but any point in the right direction will help me greatly. – e_hoog Mar 06 '15 at 16:13
  • Thank you @CodeCaster! I was not searching with the right terminology. Much appreciated. – e_hoog Mar 06 '15 at 16:14

0 Answers0