2010-07-28 32 views
14

Tôi đang gặp sự cố khi tiêm các dịch vụ phụ thuộc vào dịch vụ WCF của tôi bằng Autofac 1.4.5. Tôi đã đọc và theo dõi các Autofac wiki page on WcfIntegration nhưng gỡ lỗi của tôi cho thấy rằng dịch vụ WCF của tôi được tạo ra bởi phương pháp System.ServiceModel.Dispatcher.InstanceBehavior.GetInstance() và không phải bởi AutofacWebServiceHostFactory. Tôi đang làm gì sai?Sử dụng Autofac cho DI vào dịch vụ WCF được lưu trữ trong ứng dụng ASP.NET

tôi đã thiết lập ajax.svc tập tin của tôi trông giống như một trong những ví dụ để sử dụng với WebHttpBinding:

<%@ ServiceHost Language="C#" Debug="true" 
    Service="Generic.Frontend.Web.Ajax, Generic.Frontend.Web" 
    Factory="Autofac.Integration.Wcf.AutofacWebServiceHostFactory, 
      Autofac.Integration.Wcf" %> 

My lớp dịch vụ WCF Ajax được định nghĩa như thế này:

namespace Generic.Frontend.Web 
{ 
    [ServiceContract] 
    [AspNetCompatibilityRequirements(
     RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)] 
    public class Ajax 
    { 
     public MapWebService MapWebService { get; set;} 

     public Ajax() { 
      // this constructor is being called 
     } 

     public Ajax(MapWebService mapWebService) 
     { 
      // this constructor should be called 
      MapWebService = mapWebService; 
     } 

     [WebGet(ResponseFormat = WebMessageFormat.Json)] 
     [OperationContract(Name = "mapchange")] 
     public MapChangeResult ProcessMapChange(string args) 
     { 
      // use the injected service here 
      var result = MapWebService.ProcessMapChange(args); 
      return result; 
     } 
    } 
} 

Bây giờ Tôi đã sử dụng hệ thống dây điện trong số Global.asax.cs như được hiển thị trong wiki được đề cập ở trên:

var builder = new ContainerBuilder(); 
builder.RegisterModule(new AutofacModuleWebservice()); 
var container = builder.Build(); 
AutofacServiceHostFactory.Container = container; 
.210

với

class AutofacModuleWebservice : Module 
{ 
    protected override void Load(ContainerBuilder builder) 
    { 
     builder.Register<Ajax>(); 
     builder.Register<MapWebService>().ContainerScoped(); 
    } 
} 

Trong web.config của tôi, tôi có

<services> 
    <service name="Generic.Frontend.Web.Ajax"> 
     <endpoint address="http://mysite.com/ajax.svc/" binding="webHttpBinding" 
        contract="Generic.Frontend.Web.Ajax" /> 
    </service> 
</services> 

.

Dịch vụ đã hoạt động tốt nhưng tôi không thể nhận được các bit Autofac (đọc: tạo/tiêm) để hoạt động. Bất kỳ ý tưởng?

Edit: Loại bỏ các constructor mặc định không may dẫn đến ngoại lệ sau đây:

System.InvalidOperationException: 
The service type provided could not be loaded as a service because it does not 
have a default (parameter-less) constructor. To fix the problem, add a default 
constructor to the type, or pass an instance of the type to the host. 

Chúc mừng, Oliver

+0

Bạn đã giải quyết vấn đề này chưa? Tôi có vấn đề tương tự và tôi đã đặt câu hỏi của mình ở đây -> http://stackoverflow.com/questions/16489403/using-autofac-with-ajax-enabled-wcf-service – codingjoe

+0

Thật không may, không. Đó cũng là lý do tại sao không có gì được đánh dấu là câu trả lời, tại đây: - | – Oliver

+0

Làm thế nào để bạn lưu trữ nó? iis, là, tự lưu trữ? Bạn nên viết nó xuống trong câu hỏi của bạn tôi nghĩ. Bạn viết mã khác nhau tùy thuộc vào điều này. – Johan

Trả lời

0

Hãy thử xóa các constructor mặc định Ajax và sửa đổi constructor của bạn vào đó. Nếu nó được chạy với mapWebService == null sẽ cho biết vấn đề về độ phân giải.

public Ajax(MapWebService mapWebService = null) 
    { 
     // this constructor should be called 
     MapWebService = mapWebService; 
    } 
+0

Cảm ơn gợi ý, nhưng tôi đã thực sự đã cố gắng để có hiệu lực của việc tiếp nhận System.InvalidOperationException sau: Dịch vụ loại được cung cấp không thể được tải dưới dạng dịch vụ vì nó không có hàm tạo mặc định (tham số-ít). Để khắc phục sự cố, hãy thêm hàm tạo mặc định vào loại hoặc chuyển một thể hiện của loại cho máy chủ. Đó là cách tôi nhận ra rằng Autofac thực sự không tạo ra cá thể dịch vụ. – Oliver

1

Dịch vụ của bạn có được thiết lập với InstanceContextMode.Single không? Nếu nó là sau đó wcf sẽ tạo ra dịch vụ của bạn bằng cách sử dụng constructor mặc định. Để giải quyết vấn đề này, hãy thay đổi chế độ ngữ cảnh cá thể của bạn và để autofac quản lý thời gian hoạt động của dịch vụ của bạn.

+0

Xin chào Jon, không có thiết lập nào không được cài đặt với InstanceContextMode.Single. Tôi cũng đã cố gắng đặt nó cho PerSession một cách rõ ràng - không có hiệu lực. – Oliver

+0

Nó cũng có thể là một lớp cơ sở được cấu hình với InstanceContextMode.Single (đó là trường hợp của tôi) – lvmeijer

0

Tôi chỉ có cùng một System.InvalidOperationException và giải quyết nó bằng cách thay đổi ServiceBehavior InstanceContextMode của việc thực hiện từ InstanceContextMode.PerCall thành InstanceContextMode.PerSession, có lẽ phạm vi thời gian của AutoFac của bạn không đồng bộ với việc triển khai dịch vụ web của bạn?

Để thử nghiệm tạo dịch vụ AutoFac, tôi khuyên bạn nên tạo kiểm tra đơn vị và trực tiếp giải quyết chúng vì điều này sẽ làm nổi bật mọi vấn đề và cung cấp thêm thông báo ngoại lệ có ý nghĩa. Đối với các dịch vụ có phạm vi thời gian yêu cầu, hãy tạo trang aspx thử nghiệm và giải quyết chúng một cách trực tiếp.

0

Tôi gặp sự cố tương tự và gặp phải câu hỏi này trong khi tìm kiếm câu trả lời.

Trong trường hợp của tôi, sử dụng tiêm bất động sản làm việc, và các mã trong câu hỏi đã có một tài sản có thể được sử dụng:

namespace Generic.Frontend.Web 
{ 
    [ServiceContract] 
    [AspNetCompatibilityRequirements(
     RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)] 
    public class Ajax 
    { 
     // inject the dependency here 
     public MapWebService MapWebService { get; set;} 

     [WebGet(ResponseFormat = WebMessageFormat.Json)] 
     [OperationContract(Name = "mapchange")] 
     public MapChangeResult ProcessMapChange(string args) 
     { 
      // use the injected service here 
      var result = MapWebService.ProcessMapChange(args); 
      return result; 
     } 
    } 
} 

và đăng ký sử dụng tiêm tài sản (mẫu mã từ wiki và cú pháp có thay đổi như thế này hiện đang sử dụng phiên bản 2.5.2.830):

builder.RegisterType<Ajax>().PropertiesAutowired(); 
0

Tiếp theo các hướng dẫn giải quyết nó cho tôi:

code.google.com/p/autofac/wiki/... tôi chỉ đơn giản do: builder.RegisterType();

và tôi đã theo dõi sự thay đổi của chúng để thay đổi tệp .svc.

Khi bạn xem tệp .svc của mình, bạn không nhận được bất kỳ gợi ý nào về sự cố xảy ra ở đó có btw?

Bạn lưu trữ nó throu IIS và không sử dụng được, tôi không nhìn thấy mã của bạn cho global.asax.cs trọng

Thêm tập tin toàn cầu để giải pháp của bạn và có bạn thực hiện:

protected void Application_Start(object sender, EventArgs e) 
     { 
      // build and set container in application start 
      IContainer container = AutofacContainerBuilder.BuildContainer(); 
      AutofacHostFactory.Container = container; 


     } 

AutofacContainerBuilder là công cụ xây dựng vùng chứa của tôi.

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