我在这篇文章前面加上警告。虽然我是一个相当称职的程序员(如果在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实例。
我想我已明确定义了我的问题。如果我需要进一步详细说明或改写我的帖子,请告诉我。
答案 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)
看起来并不合适。