2010-11-22 3 views
0

Сценарий:Ограничение клиент знание документооборота

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

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

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

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

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

ответ

1

Я сделал это в нескольких проектах, и он работает отлично. И нет необходимости использовать 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 с типом сообщением в и и один OperationContract с Name = «*» и вы можете HANDCRAFT вашего WCF сообщения по мере необходимости.

+0

По-видимому, по-прежнему требуется глубокое знание рабочего процесса на клиенте. Что, если все, что я знаю, это строка "[OrderEntry | {http://www.myurl.com/} IOrderEntryService: InternalReceiveMessage]" (Экземпляры.ActiveBookmarks из базы данных InstanceStore) и URL? Я установил соглашение о том, что операции будут принимать строковый параметр и возвращать пустоту, но я не знаю, какие операции доступны заранее. Другой разработчик мог бы повторно развернуть рабочий процесс с помощью новой операции OrderReview, и моему клиентскому приложению необходимо динамически ее обнаруживать и вызывать. – TrueWill 2010-11-23 20:48:39

Смежные вопросы