.NET WCF 访问本地对象

发布于 2024-10-12 18:03:54 字数 2227 浏览 4 评论 0原文

我在这篇文章的前言中提出了一个警告。虽然我是一名相当有能力的程序员(如果刚从大学毕业 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 实例。

我想我已经清楚地定义了我的问题。如果我需要进一步阐述或改写我的帖子,请告诉我。

I preface this post with a warning. While I am a fairly competent programmer (if that can be the case when one is fresh out of 4 years of college), I am very new to Windows programming. I am programming in .NET C# (version 4).

I am attempting to create a Windows Service that can be configured remotely via a "client" configuration utility (Windows Forms app). The reason I chose WCF for IPC is because my understanding is that WCF is a replacement for Windows Remoting and that Remoting is being phased out.

My problem is that I can't figure out how to access an already instantiated object from the WCF instance created when the configuration utility connects to the Windows Service.

Perhaps this very simplified code block will give you more of an idea of what I'm attempting to do. (Making it up as I go. Hopefully no embarrassing errors in logic.)

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.
        */
    }
}

Basically I just want to be able to write to the ConfigManager instance that is being referenced by the MyService instance.

I think I've clearly defined my problem. Let me know if I need to further elaborate or reword my post.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

墨小墨 2024-10-19 18:03:55

你把你的配置保存在哪里?

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

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

顺便说一下,while(1==1) 看起来不太正确。

Where are you keeping your configuration?

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

If this configuration is kept in memory, then you can make it a singleton or a static object so that there's only one instance. Then you just get the single instance and modify it.

By the way, while(1==1) doesn't look right.

寒冷纷飞旳雪 2024-10-19 18:03:54

虽然使用静态字段/属性来存储配置在技术上可以解决这个问题,但我认为这是一个肮脏的黑客行为。你的代码越依赖静态字段,它的可扩展性就越差(如果在未来的某个时刻,你想在一个进程中托管两个相同的服务怎么办?),并且它对单元测试的抵抗力更强。

正确的解决方案是使用 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 上放置了另一个绑定。

While using static fields/properties for storing configuration will technically solve this problem, I would consider it a dirty hack. The more your code depends on static fields, the less scalable it is (what if, at some point in the future, you want to host two identical services in a single process?), and it becomes much more resistant to unit testing.

The correct solution to this is using InstanceContextMode.Single with the WCF framework, and create your WCF service implementation object explicitly, passing it references to whatever core objects it needs:

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

Alternatively, you can get rid of the seemingly meaningless delegation, and use your MyService object as the WCF service implementation itself. This, however, is also less desirable (in my view), since it puts another binding on MyService.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文