.NET WCF访问本地对象

时间:2011-01-17 18:24:50

标签: .net wcf windows-services remoting

我在这篇文章前面加上警告。虽然我是一个相当称职的程序员(如果在4年大学毕业的时候可能就是这种情况),我对Windows编程很新。我在.NET C#(版本4)中编程。

我正在尝试创建可以通过“客户端”配置实用程序(Windows窗体应用程序)远程配置的Windows服务。我选择WCF用于IPC的原因是因为我的理解是WCF是Windows Remoting的替代品,而Remoting正在逐步淘汰。

我的问题是我无法弄清楚如何从配置实用程序连接到Windows服务时创建的WCF实例访问已实例化的对象。

也许这个非常简化的代码块可以让您更好地了解我正在尝试做什么。 (在我离开的时候做好准备。希望在逻辑上没有令人尴尬的错误。)

class Blah
{
    /*
     * Create configuration object that is read
     * by myApp and written to by myServ.
    */
    ConfigManager confMan = new ConfigManager();

    MyService myApp = new MyService(ref confMan);
    Thread myAppT = new Thread(new ThreadStart(myApp.init));
    myAppt.Start();
    myAppT.Join();

    //The confServ will handle all of the WCF related stuff
    ConfigServer confServ = new ConfigServer(confMan);
    Thread confServT = new Thread(new ThreadStart(confServ.init));
    confServT.Start();
    confServT.Join();
}

class ConfigManager
{
    public bool someAttribute;

    public ConfigManager()
    {
    }

    public init()
    {
        someAttribute = false;
    }
}

class MyService
{
    ConfigManager confMan;

    public MyService(ref ConfigManager confMan)
    {
        this.confMan = confMan;
    }

    public int init()
    {
        while(1==1)
        {
            if(confMan.someAttribute == true)
                return 0;
        }
    }
}

class ConfServ
{
    ConfigManager confMan;
    public ConfServ(ref ConfigManager confMan)
    {
        this.confMan = confMan;
    }

    public void init()
    {
        //Do all the ServiceHost WCF stuff
    }
}

[ServiceContract]
public interface IModConfig
{
    [OperationContract]
    void changeFalse();
    void changeTrue();
}

/*
 * How can I get my instance of confMan 
 * into this instance of ModConfig
*/
class ModConfig: IModConfig
{
    public void changeFalse()
    {
        /*
         * I want to change confMan.someAttribute
         * to false here.
        */
    }

    public void changeTrue()
    {
        /*
         * I want to change confMan.someAttribute
         * to true here.
        */
    }
}

基本上我只是希望能够写入MyService实例引用的ConfigManager实例。

我想我已明确定义了我的问题。如果我需要进一步详细说明或改写我的帖子,请告诉我。

2 个答案:

答案 0 :(得分:1)

虽然使用静态字段/属性来存储配置在技术上可以解决这个问题,但我认为这是一个肮脏的黑客。您的代码依赖于静态字段越多,它的可伸缩性就越低(如果在未来的某个时刻,您希望在单个进程中托管两个相同的服务?),它对单元测试的抵抗力就会大大提高。 / p>

正确的解决方案是将InstanceContextMode.Single与WCF框架一起使用,并显式创建WCF服务实现对象,将其引用传递给它需要的任何核心对象:

MyService app = ...
...

WcfService myService = new WcfService( app );
ServiceHost wcfHost = new ServiceHost( myService );
wcfHost.Open();

...

[ServiceBehavior( InstanceContextMode=InstanceContextMode.Single )]
public class WcfService : IYourWcfContract
{
    private MyService _app;

    public WcfService( MyService app )
    {
        _app = app;
    }

    // Implements IYourWcfContract.UpdateConfiguration
    public void UpdateConfiguration( string newConfig )
    {
        _app.UpdateConfiguration( newConfig );
    }
}

或者,您可以摆脱看似毫无意义的委托,并使用您的MyService对象作为WCF服务实现本身。然而,这也是不太理想的(在我看来),因为它对MyService提出了另一种约束。

答案 1 :(得分:0)

您在哪里保留配置?

public void changeTrue()     
{         
    // load configuration from some file, database, other storage
    // update configuration
    // persist the new configuration
} 

如果此配置保留在内存中,则可以将其设置为单个或静态对象,以便只有一个实例。然后你只需要获得单个实例并进行修改。

顺便说一下,while(1==1)看起来并不合适。