2012-04-07 28 views
9

Để biên dịch đơn điệu thành mã gốc, do đó, nó có một số hạn chế như gọi động không được phép.Monotouch/WCF: Cách sử dụng dịch vụ wcf mà không cần svcutil

Nhưng tôi có nhiều lớp trong .net, tôi sử dụng tính năng ChannelFactory để gọi dịch vụ wcf: ChannelFactory mới (myBinding, myEndpoint); Bây giờ trong monotouch, tôi nên sử dụng slsvcutil để tạo lớp proxy wcf, nhưng slsvcutil tạo ra nhiều mã không cần thiết (rất lớn), và làm cho người tiêu dùng khó kiểm tra đơn vị, do kết nối cao với cơ sở hạ tầng WCF thông qua lớp ClientBase.

Có giải pháp nào tốt hơn trừ ChannelFactory không? Tôi muốn viết mã theo cách thủ công, có nhiều quyền kiểm soát hơn đối với cách các dịch vụ được gọi như ChannelFactory.

==========

 ChannelFactory<IMyContract> factory = new ChannelFactory<IMyContract>(binding, endpointAddress); 
     return factory.CreateChannel(); 

// ==> Nó ném ngoại lệ: MonoTouch không hỗ trợ thế hệ mã proxy động. Ghi đè phương pháp này hoặc gọi của nó trở về khách hàng cụ thể ủy quyền dụ

Trả lời

13

ChannelFactory<T> có phương thức ảo CreateChannel(). Nếu điều này không được ghi đè, nó sẽ sử dụng tạo mã động, không thành công trên MonoTouch.

Giải pháp là ghi đè và cung cấp triển khai biên dịch của riêng bạn.

Dưới đây là một triển khai dịch vụ cũ của tôi mà ít nhất được sử dụng để làm việc trên MonoTouch. Tôi chia nó thành 2 lớp học một phần - lớp đầu tiên được liên kết trong tất cả các bản dựng, thứ 2 chỉ trong bản dựng iOS (cho phép cơ chế tạo động vẫn hoạt động trên các cửa sổ).
Tôi đã gỡ xuống để chỉ chứa 1 cuộc gọi dịch vụ.

TransactionService.cs:

public partial class TransactionService : ClientBase<IConsumerService>, IConsumerService 
{ 

    public TransactionService() 
    { 
    } 

    public TransactionService(string endpointConfigurationName) : 
     base(endpointConfigurationName) 
    { 
    } 

    public TransactionService(string endpointConfigurationName, string remoteAddress) : 
     base(endpointConfigurationName, remoteAddress) 
    { 
    } 

    public TransactionService(string endpointConfigurationName, EndpointAddress remoteAddress) : 
     base(endpointConfigurationName, remoteAddress) 
    { 
    } 

    public TransactionService(Binding binding, EndpointAddress remoteAddress) : 
     base(binding, remoteAddress) 
    { 
    } 

    public AccountBalanceResponse GetAccountBalance(AccountBalanceQuery query) 
    { 
     return Channel.GetAccountBalance(query); 
    } 
} 

TransactionService.iOS.cs: ConsumerServiceClientChannel mà thực hiện các cuộc gọi thông qua phản ánh)

public partial class TransactionService 
{ 
    protected override IConsumerService CreateChannel() 
    { 
     return new ConsumerServiceClientChannel(this); 
    } 

    private class ConsumerServiceClientChannel : ChannelBase<IConsumerService>, IConsumerService 
    { 

     public ConsumerServiceClientChannel(System.ServiceModel.ClientBase<IConsumerService> client) : 
      base(client) 
     { 
     } 

     // Sync version 
     public AccountBalanceResponse GetAccountBalance(AccountBalanceQuery query) 
     { 
      object[] _args = new object[1]; 
      _args[0] = query; 
      return (AccountBalanceResponse)base.Invoke("GetAccountBalance", _args); 
     } 

     // Async version 
     public IAsyncResult BeginGetAccountBalance(AccountBalanceQuery query, AsyncCallback callback, object asyncState) 
     { 
      object[] _args = new object[1]; 
      _args[0] = query; 
      return (IAsyncResult)base.BeginInvoke("GetAccountBalance", _args, callback, asyncState); 
     } 


     public AccountBalanceResponse EndGetAccountBalance(IAsyncResult asyncResult) 
     { 
      object[] _args = new object[0]; 
      return (AccountBalanceResponse)base.EndInvoke("GetAccountBalance", _args, asyncResult); 
     } 

    } 
} 

EDIT: Tôi chỉ được thử nghiệm này với các mới nhất MT (5.2) - nó không còn cần tất cả các tấm nồi hơi mà tôi đã có trong đó trước đây, chỉ cần ghi đè CreateChannel(). Tôi đã làm sạch mã mẫu để khớp.

EDIT2: Tôi đã thêm triển khai phương pháp không đồng bộ.

+0

cảm ơn bạn đã chia sẻ, tôi đã thử ngay bây giờ. – BlueSky

+0

Giải pháp của bạn thành công, cảm ơn. – BlueSky

+0

Ở đây nó nói nó không thể tìm thấy ChannelBase lớp. Và tôi không thấy làm thế nào tôi có thể sử dụng điều này với các phương pháp không đồng bộ. Cảm ơn bạn! – cheeesus

0

Tôi nghĩ rằng bạn có thể là thuật ngữ khó hiểu ở đây - ChannelFactory là một loại generic, không phải là một động.

Theo tài liệu MonoTouch, mặc dù có limitations to the Generics support in MonoTouch, KênhFactory nên vẫn ổn ở đây.

Bạn đã thử sử dụng ChannelFactory chưa?

+0

Có, tôi đã thử sử dụng ChannelFactory, tôi đã đăng mã ở trên, xin vui lòng ref, cảm ơn. – BlueSky

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