2012-11-05 8 views

Trả lời

5

Một cách để làm điều này mà tôi thường làm cho thuận tiện là tuyên bố container của bạn như là một biến toàn cầu trong Global.ascx.cs bạn nộp như:

public class MvcApplication : System.Web.HttpApplication 
{ 
    public static UnityContainer Container; 

    protected void Application_Start() 
    { 
     // assuming your initialize here 
    } 
} 

Tuy nhiên điều này là khá hack- ish.

Điều chính xác cần làm là sử dụng Unity để giải quyết bộ điều khiển của bạn (See this article on creating a unity controller factory), và sau đó cho phép thống nhất để chèn bất kỳ phụ thuộc vào bộ điều khiển của bạn khi nó giải quyết bộ điều khiển.

Vì vậy, một bộ điều khiển như:

public MyController: Controller { 

public ICacheManager CacheManager {get;set;} 

} 

Sẽ Automagically phân giải bất kỳ phụ thuộc mà chứa của bạn đã đăng ký.

+0

Cảm ơn bạn! Chính xác những gì tôi cần. – Sergey

6

Tôi giả sử bạn' tái giải quyết một số trường hợp Controller bằng cách sử dụng container. Nếu đó là trường hợp, bạn có thể có bộ điều khiển nhận IUnityContainer như một phụ thuộc giống như bất kỳ khác.

Bạn đang cố gắng làm gì? Bắt container trong các lớp học được giải quyết của bạn không phải là tuyệt vời bởi vì nó kết hợp các lớp học của bạn với container, và thường có thể được thay thế bằng các cơ chế khác.

class Program 
{ 
    static void Main(string[] args) 
    { 
     var container = new UnityContainer(); 

     var foo = container.Resolve<MyController>(); 
    } 
} 

public class MyController 
{ 
    private IUnityContainer container; 

    public MyController(IUnityContainer container) 
    { 
     this.container = container; 
    } 
} 
3

Mặc dù có thể, tốt nhất là bạn nên tránh.

Tốt nhất là bạn lấy bất kỳ phụ thuộc nào mà bộ điều khiển cần thông qua các tham số của hàm tạo. Bằng cách này, lớp (bộ điều khiển) làm cho nó rõ ràng những gì là phụ thuộc cần thiết cho nó để chạy.

Nếu được định cấu hình chính xác, vùng chứa sẽ cung cấp những phụ thuộc đó và phụ thuộc của chúng (nếu có), v.v.

Việc sử dụng vùng chứa IoC thường chỉ được giới hạn ở một nơi trong ứng dụng (được gọi là gốc thành phần ). Mọi tham chiếu/cuộc gọi thêm vào vùng chứa đều dễ bị dẫn đến số Service Locator anti-pattern. Xem bài viết được liên kết vì lý do tại sao một cách tiếp cận như vậy có thể xấu.

+0

Với điều này "Service Locator anti-pattern", làm thế nào người ta sử dụng container Resolve mà không có một Service Locator để giải quyết container ??? – enorl76

+0

@ enorl76 Các cuộc gọi của bạn tới 'container.Resolve()' nên được giới hạn ở một nơi trong ứng dụng, như tôi đã mô tả trong câu trả lời. Các thành phần kinh doanh của bạn nên không biết rằng chúng và các phụ thuộc của chúng đang được tiêm. – GolfWolf

+0

Vấn đề tôi đang thắc mắc là khi một thành phần kinh doanh chỉ cần một quy trình làm việc nhất định, nhưng tôi tin câu trả lời có lẽ là tái cấu trúc các thành phần kinh doanh một chút, nơi quy trình làm việc nhất định sẽ được đóng gói trong một thành phần kinh doanh. thành phần kinh doanh như một sự phụ thuộc của hàm tạo. – enorl76

8

Không chắc lý do tại sao bạn cần điều đó, nhưng đây là đoạn code:

public ActionResult Area51() 
    { 
     var _service = DependencyResolver.Current.GetService(typeof (IDummyService)); 

     return View(); 
    } 

Nếu những gì bạn đang cố gắng làm là tiêm một Controller, bạn nên đặt DepedencyResolver sử dụng container IoC của bạn ở đầu ứng dụng Global.asax của . Sau đó, MVC sẽ tự động phụ thuộc vào bộ điều khiển của bạn.

var container = new UnityContainer(); 
DependencyResolver.SetResolver(new Unity.Mvc4.UnityDependencyResolver(container)); 

Look đây ví dụ nữa:

http://www.dotnet-tricks.com/Tutorial/dependencyinjection/632V140413-Dependency-Injection-in-ASP.NET-MVC-4-using-Unity-IoC-Container.html