Реализация единицы работы в сервисе WCF с Autofac - PullRequest
6 голосов
/ 03 апреля 2012

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

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

Я видел Использование пользовательскихПоведение конечной точки с WCF и Autofac , что, в основном, так, как я начал, но не касается исключений.

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

1 Ответ

1 голос
/ 29 мая 2012

Брэдли Бовейнис нашел решение этой проблемы. Мы не проверили его полностью, но похоже, что оно работает:

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.

...