2012-04-03 3 views
6

Как я могу реализовать шаблон работы в службе WCF с помощью Autofac?Внедрение единицы работы в службе WCF с помощью Autofac

Внедрение одного и того же экземпляра за звонок (или в терминах Autofac LifetimeScope) модуля рабочего интерфейса в мои сервисы и репозитории легко с использованием интеграции wcf Autofac - то, что я делаю, это способ зафиксировать единицу изменений работы на возврат вызова службы WCF явно ТОЛЬКО, если не было никаких исключений.

Я видел Using a Custom Endpoint Behavior with WCF and Autofac, который в основном, как я начал, но это не касается исключений.

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

+0

Предположим, что мы зарегистрировали 'IUnitOfWork' в контейнере. Как мы можем связать с ним вызов службы и вызывать только 'SaveChanges()', если исключение не произошло? Или нам нужно взять UoW в конструкторе службы? – jgauffin

+0

Когда вы говорите служебный звонок, вы имеете в виду вызов службы WCF? Если да, то ссылка, которую я привел выше, показывает, как вы можете это сделать. Единственная проблема заключается в том, что мне еще предстоит найти способ сохранить только UoW, если при использовании AutoFac не было никаких исключений. –

+0

Вы сказали это сами =) 'то, что мне нужно, это способ зафиксировать единицу изменений работы при возврате вызова службы WCF, очевидно ТОЛЬКО, если не было никаких исключений. '. Это трудная часть и то, что я ищу. – jgauffin

ответ

1

Bradley Boveinis нашел решение этой проблемы. Мы тщательно не тестировал, но это похоже на работу:

public class UnitOfWorkAwareOperationInvoker : IOperationInvoker 
{ 
    private readonly IOperationInvoker _baseInvoker; 

    public UnitOfWorkAwareOperationInvoker(IOperationInvoker baseInvoker) 
    { 
     _baseInvoker = baseInvoker; 
    } 

    public object[] AllocateInputs() 
    { 
     return _baseInvoker.AllocateInputs(); 
    } 

    public object Invoke(object instance, object[] inputs, out object[] outputs) 
    { 
     var result = _baseInvoker.Invoke(instance, inputs, out outputs); 
     var context = OperationContext.Current.InstanceContext.Extensions.Find<AutofacInstanceContext>(); 

     try 
     { 
      context.Resolve<IUnitOfWork>().Save(); 
     } 
     catch (Exception ex) 
     { 
      var message = Message.CreateMessage(MessageVersion.Default, string.Empty); 
      new ElmahErrorHandler().ProvideFault(ex, null, ref message); 
      throw; 
     } 
     return result; 
    } 

    public IAsyncResult InvokeBegin(object instance, object[] inputs, AsyncCallback callback, object state) 
    { 
     return _baseInvoker.InvokeBegin(instance, inputs, callback, state); 
    } 

    public object InvokeEnd(object instance, out object[] outputs, IAsyncResult result) 
    { 
     return _baseInvoker.InvokeEnd(instance, out outputs, result); 
    } 

    public bool IsSynchronous 
    { 
     get { return _baseInvoker.IsSynchronous; } 
    } 
} 

Ключ находится в следующей строке:

OperationContext.Current.InstanceContext.Extensions.Find<AutofacInstanceContext>(); 

Это захватывает UOW из окружающей среды/ток/контекстная LifetimeScope.

+1

Не выполняет ли это изменения, даже если операция выдает исключение? – jgauffin

+0

@jgauffin Он не должен, как если бы возникло исключение, вызванное вызовом службы, оно будет передано на вызов _baseInvoker.Invoke (экземпляр, входы, выходы) и весь код ниже, который будет проигнорирован. – xelibrion

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