Ограничение знаний клиента о рабочем процессе - PullRequest
0 голосов
/ 22 ноября 2010

Сценарий:

  • Windows Workflow Foundation (WF) в .NET 4
  • Рабочий процесс, развернутый как служба WCF
  • Несколько операций получения, все с одинаковымипараметры
  • Имя операции соответствует имени операции
  • Использование постоянного рабочего процесса SQL Server
  • (без SharePoint)

По умолчанию знание рабочего процессавстраивается в клиенты при добавлении ссылки на сервис и создании прокси.Клиент знает, какие методы WCF доступны.

Я хочу отделить рабочий процесс от клиентов, по сути, создав «общего» клиента, который может работать с любым рабочим процессом, соответствующим определенным соглашениям.Клиент запросит хранилище экземпляров SQL, чтобы определить, какие действия / операции / закладки (и) данный экземпляр ожидал (это уже стандартный столбец - ActiveBookmarks), а затем предоставит этот выбор пользователю.

Таким образом, рабочий процесс может быть изменен без перекомпиляции / повторного развертывания клиентов.Несколько коммерческих систем BPM работают таким образом;Вы можете добавить новые клиентские действия, и они автоматически появятся в рабочей очереди клиента.Все динамически обнаруживается.

Как это можно сделать?Требуется ли использование Reflection.Emit для генерации прокси на лету?Было бы проще, если бы каждая операция использовала свой контракт на обслуживание?

1 Ответ

1 голос
/ 23 ноября 2010

Я сделал это в нескольких проектах, и он работает просто отлично.И нет необходимости использовать Reflection.Emit, так как WCF имеет всю необходимую инфраструктуру.

Например, следующий код вызовет шаблон службы рабочего процесса по умолчанию, все, что вам нужно сделать, это предоставить правильный URL.*

class Program
{
    static void Main(string[] args)
    {

        var factory = new ChannelFactory<IMyService>(new BasicHttpBinding(), new EndpointAddress("http://localhost:9199/Service1.xamlx"));
        var proxy = factory.CreateChannel();
        var response = proxy.GetData(new GetDataRequest() { Value = 42 });
        Console.WriteLine(response.Value);
        Console.ReadLine();
    }
}

[ServiceContract(Name = "IService")]
interface IMyService
{
    [OperationContract]
    GetDataResponse GetData(GetDataRequest request);
}

[MessageContract(IsWrapped = false)]
class GetDataRequest
{
    [MessageBodyMember(Name = "int", 
        Namespace = "http://schemas.microsoft.com/2003/10/Serialization/")]
    public int Value { get; set; }
}

[MessageContract(IsWrapped = false)]
class GetDataResponse
{
    [MessageBodyMember(Name = "string", 
        Namespace = "http://schemas.microsoft.com/2003/10/Serialization/")]
    public string Value { get; set; }
}

Если вам нужна большая гибкость, вы также можете создать ServiceContract с типом Message in и out и один OperationContract с Name = "*", и вы можете вручную обработать ваше сообщение WCF.

...