0

假设我有一个 Windows 窗体应用程序,应该使用 .net 从远程位置进行远程控制或影响。

据我用谷歌搜索,在该应用程序中托管 WCF 服务将是可行的方法。我已经成功地向应用程序添加了 WCF 服务,并且可以使用它启动它

    ServiceHost host = new ServiceHost(typeof(Service1));   
    host.Open();

什么是从正在运行的应用程序的其余部分获取对类的引用的好方法?
我想只有这两种方式:

  • 使用静态属性从服务方法中调用其他方法/设置属性。
  • 分配对服务类的引用?(如何为服务主机中托管的服务分配值?)

什么被认为是好的做法,或者更确切地说,过去哪种方式对你有用?

根据评论更新
我猜我正在寻找这样的东西:

    ServiceHost host = new ServiceHost(typeof(Service1));   
    host.Open();  
    (Service1)host.MyProperty = "asd";

我似乎找不到如何将 ServiceHost(或其属性)转换为 Service1 的实例。那可能会解决我所有的问题;)

4

2 回答 2

4

您不能真正根据评论执行您添加的操作:

ServiceHost host = new ServiceHost(typeof(Service1));
host.Open();
(Service1)host.MyProperty = "asd";

因为那时Service1还没有创建类的实例。并且它们只会在新的服务请求到达时创建。

一种替代方法是使用自定义实例提供程序(如下面的代码所示),在 WCF 运行时使用服务实例之前,您可以在其中引用它。您可以在http://blogs.msdn.com/b/carlosfigueira/archive/2011/05/31/wcf-extensibility-iinstanceprovider.aspx阅读有关实例提供程序的更多信息。

public class StackOverflow_10932251
{
    [ServiceContract]
    public interface ITest
    {
        [OperationContract]
        string Echo(string text);
    }
    public class Service : ITest
    {
        public string MyProperty { get; set; }
        public string Echo(string text)
        {
            Console.WriteLine("Inside Service.Echo, MyProperty = {0}", this.MyProperty);
            return text;
        }
    }
    static Binding GetBinding()
    {
        var result = new WSHttpBinding(SecurityMode.None);
        return result;
    }
    public class MyInstanceProvider : IEndpointBehavior, IInstanceProvider
    {
        string propertyValue;
        public MyInstanceProvider(string propertyValue)
        {
            this.propertyValue = propertyValue;
        }

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

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

        public void ApplyDispatchBehavior(ServiceEndpoint endpoint, EndpointDispatcher endpointDispatcher)
        {
            endpointDispatcher.DispatchRuntime.InstanceProvider = this;
        }

        public void Validate(ServiceEndpoint endpoint)
        {
        }

        public object GetInstance(InstanceContext instanceContext, Message message)
        {
            return new Service { MyProperty = this.propertyValue };
        }

        public object GetInstance(InstanceContext instanceContext)
        {
            return new Service { MyProperty = this.propertyValue };
        }

        public void ReleaseInstance(InstanceContext instanceContext, object instance)
        {
        }
    }
    public static void Test()
    {
        string baseAddress = "http://" + Environment.MachineName + ":8000/Service";
        ServiceHost host = new ServiceHost(typeof(Service), new Uri(baseAddress));
        ServiceEndpoint endpoint = host.AddServiceEndpoint(typeof(ITest), GetBinding(), "");
        endpoint.Behaviors.Add(new MyInstanceProvider("asd"));
        host.Open();
        Console.WriteLine("Host opened");

        ChannelFactory<ITest> factory = new ChannelFactory<ITest>(GetBinding(), new EndpointAddress(baseAddress));
        ITest proxy = factory.CreateChannel();
        Console.WriteLine(proxy.Echo("Hello"));

        ((IClientChannel)proxy).Close();
        factory.Close();

        Console.Write("Press ENTER to close the host");
        Console.ReadLine();
        host.Close();
    }
}
于 2012-06-07T13:37:25.983 回答
1

当您创建ServiceHost和调用Open时,您的服务开始侦听请求。默认行为(尽管您可以更改此行为)是Service1仅在处理客户端请求时创建实例。换句话说,只要有客户端请求,ServiceHost就会创建一个实例,Service1然后调用其适当的方法(客户端调用的任何服务操作)来处理请求。因此,您不会尝试检索(当然也不能强制转换)Service1来自的实例(除非有客户端请求,否则ServiceHost没有实例)。Service1

如果您提供一个示例说明您为什么需要将 aServiceHost转换为Service1,我们也许可以提供替代方法。

于 2012-06-07T13:38:03.873 回答