2012-04-03 41 views
6

Làm cách nào để triển khai đơn vị công việc trong dịch vụ WCF với Autofac?Thực hiện đơn vị công việc trong dịch vụ WCF với Autofac

Tiêm cùng một trường hợp cho mỗi cuộc gọi (hoặc trong điều kiện Autofac LifetimeScope) của đơn vị giao diện công việc vào dịch vụ và kho lưu trữ của tôi rất dễ dàng bằng cách sử dụng tích hợp wcf của Autofac - những gì tôi sau là một cách để cam kết đơn vị thay đổi công việc trả lại cuộc gọi dịch vụ WCF rõ ràng CHỈ nếu không có bất kỳ ngoại lệ nào.

Tôi đã xem Using a Custom Endpoint Behavior with WCF and Autofac về cơ bản là cách tôi bắt đầu nhưng điều đó không giải quyết ngoại lệ.

Hiện tại những gì tôi có là IOperationInvoker bắt đầu đơn vị công việc trong Gọi và cam kết chỉ khi không có bất kỳ ngoại lệ nào. Vấn đề với cách tiếp cận này là tôi cần phải giải quyết đơn vị công việc của mình bên trong phương thức Invoke mang lại cho tôi một trường hợp khác với trường hợp được tiêm vào các dịch vụ và kho lưu trữ của tôi bằng cách sử dụng AutofacInstanceProvider.

+0

Giả sử rằng chúng tôi đã đăng ký 'IUnitOfWork' trong vùng chứa. Làm thế nào chúng ta có thể bọc một cuộc gọi dịch vụ với nó và chỉ gọi 'SaveChanges()' nếu không có ngoại lệ nào xảy ra? Hay chúng ta phải lấy UoW trong constructor dịch vụ? – jgauffin

+0

Khi bạn nói cuộc gọi dịch vụ, bạn có nghĩa là cuộc gọi dịch vụ WCF không? Nếu có, thì liên kết tôi đã cung cấp ở trên cho thấy cách bạn có thể làm điều đó. Vấn đề duy nhất là tôi vẫn chưa tìm được cách để chỉ lưu UoW nếu không có bất kỳ ngoại lệ nào khi sử dụng AutoFac. –

+0

Bạn đã nói nó =) 'những gì tôi sau là một cách để cam kết đơn vị thay đổi công việc khi trả lại cuộc gọi dịch vụ WCF rõ ràng CHỈ nếu không có bất kỳ ngoại lệ nào. '. Đó là phần khó khăn và những gì tôi đang tìm kiếm. – jgauffin

Trả lời

1

Bradley Boveinis đã tìm ra giải pháp cho vấn đề này. Chúng tôi đã không kiểm tra kỹ lưỡng nó nhưng nó dường như làm việc:

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; } 
    } 
} 

Điều quan trọng là trong dòng sau:

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

này grabs UOW ra khỏi môi trường xung quanh/hiện tại/ngữ cảnh LifetimeScope.

+1

Nó không cam kết những thay đổi ngay cả khi hoạt động ném một ngoại lệ? – jgauffin

+0

@jgauffin Nó không nên, như thể có một ngoại lệ ném trong cuộc gọi dịch vụ, nó sẽ được ném vào _baseInvoker.Invoke (ví dụ, đầu vào, đầu ra đầu ra) gọi và tất cả các mã dưới đây sẽ bị bỏ qua. – xelibrion

Các vấn đề liên quan