2012-06-12 34 views
7

Tôi đang cố gắng triển khai Dependency injection trong ứng dụng MVC của mình. Tôi đang sử dụng Unity.Mvc3.dll cho IoC. Tôi chỉ tự hỏi làm thế nào Unity không thể đăng ký các loại từ một hội đồng khác. Dưới đây là các mã:Unity: Không thể đăng ký loại từ assembly khác nhau

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

    RegisterGlobalFilters(GlobalFilters.Filters); 
    RegisterRoutes(RouteTable.Routes); 

    var container = new UnityContainer(); 

    // ok: register type from this assembly 
    container.RegisterType<IMessages, Messages>(); 

    // fail: register type from another assembly (service reference) 
    container.RegisterType<IPlayerService, PlayerService>(); 

    DependencyResolver.SetResolver(new UnityDependencyResolver(container)); 
} 

public class UnityDependencyResolver : IDependencyResolver 
{ 
    private readonly IUnityContainer _container; 

    public UnityDependencyResolver(IUnityContainer container) 
    { 
     this._container = container; 
    } 

    public object GetService(Type serviceType) 
    { 
     try 
     { 
      return _container.Resolve(serviceType); 
     } 
     catch (Exception ex) 
     { 
      throw ex; 
     } 
    } 

    public IEnumerable<object> GetServices(Type serviceType) 
    { 
     try 
     { 
      return _container.ResolveAll(serviceType); 
     } 
     catch (Exception ex) 
     { 
      throw ex; 
     } 
    } 
} 

Cách sử dụng trong điều khiển MVC:

[Dependency] 
public IPlayerService PlayerService { get; set; } 

[Dependency] 
public IMessages Messages { get; set; } 


public ActionResult Index() 
{ 
    PlayerMessageViewModel vm = new PlayerMessageViewModel(); 
    vm.Messages = Messages; // success! 
    vm.Players = PlayerService.Get(); // fail: null reference exception :PlayerService 

    return View(vm); 
} 

PlayerService luôn là null trong khi tin nhắn là OK.

Đây là PlayerService Lớp

public class PlayerService : IPlayerService 
{ 
    private readonly MyDbEntities _dbContext; 

    public PlayerService() 
    { 
     _dbContext = new MyDbEntities(); 
    } 

    public PlayerService(MyDbEntities dbContext) 
    { 
     _dbContext = dbContext; 
    } 


    public IQueryable<Player> Get() 
    { 
     return _dbContext.Players.AsQueryable(); 
    } 
} 

đây là Thông báo lỗi hoàn

Nghị quyết của sự phụ thuộc thất bại, type = "System.Web.Mvc.IControllerFactory", name = "(không ai)".
Đã xảy ra ngoại lệ trong khi: trong khi giải quyết.
Ngoại lệ là: InvalidOperationException - Loại hiện tại, System.Web.Mvc.IControllerFactory, là một giao diện và không thể được xây dựng. Bạn đang thiếu một ánh xạ kiểu?

Trả lời

6

bằng đoàn kết mặc định chọn các nhà xây dựng với các thông số nhất, vì vậy tôi nghĩ rằng nó sẽ cố gắng sử dụng wi constructor thứ hai thứ dbContext tham số, mà nó không thể giải quyết. Nếu bạn đánh dấu hàm tạo mặc định của mình bằng thuộc tính [InjectionConstructor] thì hy vọng rằng sẽ giải quyết được sự cố của bạn

+0

sẽ làm, nhờ – lincx

+0

thuộc tính InjectionConstructor thư viện nào được bao gồm? – lincx

+0

http://msdn.microsoft.com/en-us/library/microsoft.practices.unity.injectionconstructorattribute(v=pandp.20).aspx –

7

Bạn đang ẩn tất cả các ngoại lệ với catch { return null; } cố gắng xóa nó và xem ngoại lệ được ném trong khi giải quyết. Tôi nghĩ rằng ngoại lệ được ném vào trong constructor PlayerService.

EDIT:

Từ http://mvchosting.asphostcentral.com/post/ASPNET-MVC-3-Hosting-Problem-in-implementing-IControllerActivator-in-ASPNET-MVC-3.aspx

Khi một ứng dụng MVC bắt đầu cho lần đầu tiên, giải quyết phụ thuộc được gọi với các loại sau đây theo thứ tự sau:

  • IControllerFactory
  • IControllerActivator
  • HomeController

Nếu bạn không thực hiện phân giải của bạn để trở về null nếu một loại không phải là đăng ký thì có thể bạn sẽ kết thúc khi nhìn thấy một lỗi tương tự như:

Các loại hiện nay, System.Web .Mvc.IControllerFactory, là một giao diện và không thể được xây dựng

+0

cần nhấn ctor mặc định phải không? Tôi không thể có được trình gỡ lỗi đi đến breakpoint trong ctor. – lincx

+0

Yep, 'public PlayerService()' –

+0

Tôi loại bỏ null và thay thế ném ngoại lệ và đây là những gì tôi nhận được 'loại hiện tại, System.Web.Mvc.IControllerFactory, là một giao diện và không thể được xây dựng. Bạn đang thiếu một ánh xạ kiểu? ' – lincx

2

Bạn đang vi phạm hợp đồng IDependencyResolver. Nó sẽ trả lại null cho các loại không thể giải quyết được. Vấn đề với Unity là nó cố gắng xây dựng tất cả các lớp mà nó có thể tìm thấy, cho dù chúng có được đăng ký trong thùng chứa hay không.

Do đó, không thể xây dựng một lớp ở đâu đó.

Ngoài ra còn có gói Unity.Mvc3 có sẵn trong nuget.

+0

bạn đang nói không có công việc nào liên quan đến vấn đề này? – lincx

+0

nó thực sự ban đầu trả về null nhưng tôi chỉ thay thế ngoại lệ throe để xem lỗi thực tế như được đề xuất bởi các poster khác. – lincx

+1

'Throw' của bạn ẩn đi vấn đề mà bạn nhận được từ khi bắt đầu vì' IControllerActivator' được gọi trước khi bất kỳ bộ điều khiển nào được gọi. Thay đổi trở lại để trở về null và LOG tất cả các trường hợp ngoại lệ (hoặc đặt một điểm break trong khối catch) – jgauffin

0

Loại hiện tại, (EX-DI.IBLL.IEmployee), là giao diện và không thể được xây dựng. Bạn đang thiếu một ánh xạ kiểu?

Ans - Chỉ trong Unity.config.cs thêm dòng sau Thye

public static class UnityConfig 
    { 
     public static void RegisterComponents() 
     { 
      var container = new UnityContainer(); 

      // register all your components with the container here 
      // it is NOT necessary to register your controllers 

      **container.RegisterType<IEmployee,EmployeeManager>();** 
//this could be your interface and the class implementing the interface. 

      DependencyResolver.SetResolver(new UnityDependencyResolver(container)); 
     } 
    } 
Các vấn đề liên quan