.NET WCF доступ к локальным объектам - PullRequest
0 голосов
/ 17 января 2011

Я предваряю этот пост предупреждением.Несмотря на то, что я довольно компетентный программист (если это может быть в случае, когда кто-то только что поступил после 4-х лет обучения в колледже), я очень новичок в программировании Windows.Я программирую на .NET C # (версия 4).

Я пытаюсь создать службу Windows, которую можно настроить удаленно с помощью утилиты конфигурации «клиент» (приложение Windows Forms).Причина, по которой я выбрал WCF для IPC, заключается в том, что, насколько я понимаю, WCF является заменой для Windows Remoting, и что Remoting постепенно прекращается.

Моя проблема в том, что я не могу понять, как получить доступ к уже созданномуобъект из экземпляра WCF, созданный при подключении утилиты конфигурации к службе Windows.

Возможно, этот очень упрощенный блок кода даст вам больше представления о том, что я пытаюсь сделать.(Делая это по ходу дела. Надеюсь, никаких смущающих ошибок в логике.)

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

По сути, я просто хочу иметь возможность записи в экземпляр ConfigManager, на который ссылается экземпляр MyService.

Мне кажется, я четко определил свою проблему.Дайте мне знать, если мне нужно уточнить или перефразировать мой пост.

Ответы [ 2 ]

1 голос
/ 18 января 2011

Хотя использование статических полей / свойств для хранения конфигурации технически решит эту проблему, я бы посчитал это грязным хаком. Чем больше ваш код зависит от статических полей, тем менее он масштабируем (что если в какой-то момент в будущем вы захотите разместить два одинаковых сервиса в одном процессе?), И он станет намного более устойчивым к модульному тестированию.

Правильное решение этой проблемы - использование 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.

0 голосов
/ 18 января 2011

Где вы храните свою конфигурацию?

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

Если эта конфигурация хранится в памяти, вы можете сделать ее одноэлементным или статическим объектом, чтобы был только один экземпляр.Тогда вы просто получаете один экземпляр и модифицируете его.

Кстати, while(1==1) выглядит неправильно.

...