2009-06-23 6 views

Trả lời

1

Bạn có hai tùy chọn

Tùy chọn đầu tiên là viết ActionInvoker tùy chỉnh, không khó bằng âm thanh. Hãy xem blog post này. Nó đặc biệt giao dịch với NInject, nhưng Unity hỗ trợ việc tiêm thuộc tính để bạn có thể sửa đổi ví dụ để sử dụng Unity.

Đây là tùy chọn kết hợp Vùng chứa IoC của bạn và không được khuyến nghị.

public class MyFilter 
{ 
    IMyService MyService {get; set;} 

    MyFilter() : MyFilter(MyUnityContainer.Resolve<IMyService>()) 
    { } 

    MyFilter(IMyService service) 
    { 
    MyService = service; 
    } 
} 
+0

Tôi đã cố gắng giải pháp được tìm thấy trong các bài viết trên blog nhưng có vẻ là một số khác biệt giữa Unity và Ninject, nếu không ở đâu đó, mã của một ai đó là sai :). Các bộ lọc chỉ đọc theo thời gian chúng được ghi đè vào "InvokeExceptionFilters" bị ghi đè. Vì vậy, tôi có thể khai báo một bộ lọc MỚI và chèn phụ thuộc, nhưng nếu tôi cố gắng và tiêm phụ thuộc vào danh sách được cung cấp của ExceptionFilters, không có gì xảy ra. Tôi có thể tạo bộ lọc mới và chuyển nó lên lớp cơ sở, nhưng sau đó tôi sẽ mất tất cả thông tin khai báo được cung cấp trên chính thuộc tính. –

2

Ok, đã tìm ra.

Chủ yếu là tôi đã sử dụng giải pháp của Ben ở trên từ bài đăng trên blog mà anh ấy đã chỉ ra.

Vấn đề là Unity hoạt động hơi khác một chút.

Bạn không thể tiêm trực tiếp phụ thuộc vào bộ lọc, vì chúng thuộc loại IActionFilter và IExceptionFilter tương ứng. Điều này khiến tôi tin rằng họ là người chỉ đọc, điều đó không phải như vậy. Nó chỉ là Unity cần phải biết loại rõ ràng để tiêm.

Vì vậy, trong phương pháp ghi đè do bài viết cung cấp, người dùng Unity cần truy vấn bộ lọc cho các loại được đề cập và sau đó tạo chúng lên.

public UnityActionInvoker(IUnityContainer container, IList<Type> typesToInject) 
     { 
      _container = container; 
      _typesToInject = typesToInject; 
     } 

Và sau đó trong phương pháp ghi đè, làm một cái gì đó như thế này:

var needsInjection = filters.Where(filter => typesToInject.Contains(filter.GetType())); 

Một chút lộn xộn, nhưng nó chỉ cần được thực hiện một lần, và giữ mọi thứ tách riêng như Ben gợi ý.

Bí quyết khác là bạn không thể gọi _container.BuildUp (bộ lọc) bên trong vòng lặp foreach, bởi vì bộ lọc chỉ đọc trong ngữ cảnh đó.

1

Tôi cũng đã gặp vấn đề này và hiện đang có giải pháp làm việc. Nó tương tự như giải pháp được mô tả ở trên nhưng với một số khác biệt nhỏ và cũng với mã Unity đầy đủ được thêm vào.

Trước tiên, tôi sẽ sử dụng tính năng tiêm tài sản vì lý do được mô tả ở trên và, như trên, tôi sẽ sử dụng phương pháp BuildUp trên Unity để tiêm các thuộc tính vào Bộ lọc đã tạo.

Để thực hiện việc này, tôi có tất cả các Bộ điều khiển của mình kế thừa từ một lớp cơ sở tùy chỉnh mới. Trong lớp cơ sở đó, tôi ghi đè phương thức CreateActionInvoker để thiết lập ActionInvoker tùy chỉnh của riêng mình.

Protected Overrides Function CreateActionInvoker() As System.Web.Mvc.IActionInvoker 
    Return CustomActionInvoker 
End Function 

Sau đó, trong CustomActionInvoker, tôi ghi đè phương thức GetFilters.

Protected Overrides Function GetFilters(ByVal controllerContext As ControllerContext, ByVal actionDescriptor As ActionDescriptor) As FilterInfo 
    Dim info = MyBase.GetFilters(controllerContext, actionDescriptor) 

    For Each MyAuthorizationFilter In info.AuthorizationFilters 
     MvcApplication.Container.BuildUp(MyAuthorizationFilter.GetType, MyAuthorizationFilter) 
    Next 

    For Each MyActionFilter In info.ActionFilters 
     MvcApplication.Container.BuildUp(MyActionFilter.GetType, MyActionFilter) 
    Next 

    For Each MyResultFilter In info.ResultFilters 
     MvcApplication.Container.BuildUp(MyResultFilter.GetType, MyResultFilter) 
    Next 

    For Each MyExceptionFilter In info.ExceptionFilters 
     MvcApplication.Container.BuildUp(MyExceptionFilter.GetType, MyExceptionFilter) 
    Next 

    Return info 
End Function 

Ngược lại với những gì được nói ở trên, tôi không thấy rằng việc tích tụ bên trong Vòng lặp cho mỗi gây ra bất kỳ sự cố nào.Tôi cũng đã vượt qua vấn đề ban đầu chỉ có đối tượng được tham chiếu thông qua một giao diện bằng cách sử dụng một trong các tình trạng quá tải khác của phương thức BuildUp có một System.Type cũng như đối tượng hiện có.

Với tất cả các công việc trên, giờ đây tôi có thể đưa các phụ thuộc vào Bộ lọc của tôi.

Bất kỳ nhận xét và suy nghĩ nào được đánh giá cao.

Cheers Mike