2012-10-22 4 views
11

Nếu tôi muốn thực hiện một dependency injection cho bộ điều khiển ASP.NET MVC, tôi có thể sử dụng giao diện IControllerFactory để tạo ra một lớp nhà máy và sau đó đăng ký nó trong Global.asax.cs, như:Có HttpControllerBuilder nào cho ASP.NET Web API không?

ControllerBuilder.Current.SetControllerFactory(controllerFactory) 

(tham khảo: http://www.dotnetcurry.com/ShowArticle.aspx?ID=786)

Bây giờ câu hỏi của tôi là:

Làm thế nào tôi có thể thiết lập một nhà máy cho một lớp có nguồn gốc IHttpControllerActivator?

Liệu chúng ta có một cái gì đó trong ASP.NET MVC 4.0 như:

HttpControllerBuilder.Current.SetApiControllerActivator(httpControllerActivator) 

?


Cập nhật:

Tôi muốn thêm mã hiện tại của tôi, nó có thể hữu ích để hiểu được trường hợp:

HttpControllerActivator tùy chỉnh của tôi:

public class MyCustomApiActivator : DefaultHttpControllerActivator 
            //or IHttpControllerActivator ? 
{ 
    private readonly Dictionary<string, Func<HttpRequestMessage, IHttpController>> _apiMap; 

    public MyCustomApiActivator(IMyRepository repository) 
    { 
     if (repository == null) 
     { 
      throw new ArgumentException("repository"); 
     } 
     _apiMap = new Dictionary<string, Func<HttpRequestMessage, IHttpController>>(); 
     controllerMap["Home"] = context => new HomeController(); 
     _apiMap["MyCustomApi"] = context => new MyCustomApiController(repository); 
    } 

    public IHttpController Create(HttpRequestMessage request, HttpControllerDescriptor controllerDescriptor, Type controllerType) 
    { 
     if(_apiMap.ContainsKey(controllerType.Name)) 
      return _apiMap[controllerType.Name](request); 
     return null; 
    } 
} 

thành phần của tôi gốc:

public class CompositionRoot 
{ 
    private readonly IHttpControllerActivator _apiControllerActivator; 

    public CompositionRoot() 
    { 
     _apiControllerActivator = CompositionRoot.CreateHttpControllerActivator(); 
    } 

    public IHttpControllerActivator ApiControllerActivator 
    { 
     get { return _apiControllerActivator; } 
    } 

    private static IHttpControllerActivator CreateHttpControllerActivator() 
    { 
     string defaultRepositoryTypeName = ConfigurationManager.AppSettings["DefaultRepositoryTypeName"]; 
     var defaultRepositoryType = Type.GetType(defaultRepositoryTypeName, true); 
     var defaultRepository = (IMyRepository)Activator.CreateInstance(defaultRepositoryType); 

     var apiController = new MyCustomApiActivator(defaultRepository); 
     return apiController; 
    } 
} 

Cuối cùng này là bên trong của tôi Global.asax.cs, mà tôi cần một thủ thuật:

protected void Application_Start() 
    { 
     AreaRegistration.RegisterAllAreas(); 

     WebApiConfig.Register(GlobalConfiguration.Configuration); 
     FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters); 
     RouteConfig.RegisterRoutes(RouteTable.Routes); 
     BundleConfig.RegisterBundles(BundleTable.Bundles); 


     var root = new CompositionRoot(); 
     //The following line raise this compile-time error: 
     // cannot convert from 'System.Web.Http.Dispatcher.IHttpControllerActivator' 
     //    to 'System.Web.Mvc.IControllerFactory' 
     ControllerBuilder.Current.SetControllerFactory(root.ApiControllerActivator); 
    } 

Trả lời

8

Đánh dấu SEEMANN, tác giả của Dependency Injection trong .NET, có một loạt ngắn trên DI với ASP.NET WebAPI.

Ông đặt gốc thành phần bên trong một IHttpControllerActivator

  1. Dependency Injection and Lifetime Management with ASP.NET Web API
  2. Dependency Injection in ASP.NET Web API with Castle Windsor

lẽ giúp.


Cập nhật

GlobalConfiguration.Configuration.Services.Replace(
    typeof(IHttpControllerActivator), 
    new PoorMansCompositionRoot()); 

Thanh ghi tùy chỉnh của bạn HttpControllerActivator trên toàn cầu.

+0

Vì lý do nào phương pháp 'Create' không kích hoạt? Tôi quay trở lại một bộ điều khiển chung 'công IHttpController Tạo ( HttpRequestMessage yêu cầu, HttpControllerDescriptor controllerDescriptor, Loại _controllerType) {return (IHttpController) mới GenericApiController (); } ' – Bellash

1

Trong ASP.NET Web API HttpControllerDispatcher có trách nhiệm xây dựng bộ điều khiển. Nó hoạt động với DependecyResolver theo mặc định nhưng nếu bạn muốn mở rộng chức năng của nó, bạn cần phải ghi đè lên phương thức SendAsync của nó và đăng ký lại nó.

Ví dụ:

public class MyCustomDispatcher : HttpControllerDispatcher { 

    protected override Task<HttpResponseMessage> SendAsync(
     HttpRequestMessage request, 
     CancellationToken cancellationToken) { 

     // Do your stuff here 

     // According to your requirements, either run its default functionality 
     // or return your own stuff 
     return base.SendAsync(request, cancellationToken); 
    } 
} 

Lưu ý:

Tuy nhiên, tôi đã không thể tìm thấy một cách thanh lịch để thay thế mặc định một trên toàn cầu. Bạn có thể thay thế một tuyến đường mặc định một cách dễ dàng bằng cách đính kèm bộ điều phối tùy chỉnh này vào một tuyến đường nhưng dường như không có cách nào là cách thực hiện điều này trên toàn cầu. Tôi đã mở ra một cuộc thảo luận về điều đó tại khu vực dự án : http://aspnetwebstack.codeplex.com/discussions/400366