开发者

.NET WCF access to local objects

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 开发者_JAVA百科MyService instance.

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


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.


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.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜