如何允许Windows服务中托管的WCF服务访问在Windows服务中实例化的对象?

时间:2015-03-06 15:57:50

标签: c# wcf service

我工作的公司有一个CRM应用程序,您只能从他们的SDK以编程方式访问。 SDK有一个Framework对象,它有一个LogOn()方法。

我有一个托管在Windows服务中的WCF服务。

当Windows服务启动时,它将实例化Framework对象并运行LogOn()。如果成功,则启动WCF服务。

WCF服务中的方法需要能够访问Framework对象才能执行我想要的任务。

Framework对象位于Windows服务中的位置:

// 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();
        }
    }

我想要访问该对象:

public class ACTWcfSvc : IACTWcfSvc
{
}

如何从WCF服务访问Framework对象?我将它传递给ServiceHost吗?我是否在ACTWcfSvc的构造函数中执行此操作?

编辑:

按照CodeCaster给我的链接,我能够解决我的问题。 How do I pass values to the constructor on my wcf service?

以下是它如何运作:

在我使用的Windows服务任务的OnStart()方法中

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

我在链接中列出了这些类,并将“IDependency dep”替换为“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
}

在我的WCF服务构造函数中,我添加了:

 public class ACTWcfSvc : IACTWcfSvc
{
    ActFramework actFwk;

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

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

在服务界面中我有:

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

现在在客户端程序中,我可以运行GetACTCurrentUser()方法,并根据需要返回当前用户的用户名。

希望这有助于某些人了解如何做到这一点。

0 个答案:

没有答案