【问题标题】:Constructor DI + Unity 2.0 + issue with resolving dependency构造函数 DI + Unity 2.0 + 解决依赖问题
【发布时间】:2012-01-12 22:02:03
【问题描述】:

控制器:

public class HomeController : Controller
{
    IEmployeeTask _employeeTask;

    public HomeController()
    {
        _employeeTask = new UnityContainer().Resolve<IEmployeeTask>();
    }

    public HomeController(IEmployeeTask employeeTask)
    {
        _employeeTask = employeeTask;
    }

    public ActionResult Index()
    {
        ViewBag.Message = "Welcome to ASP.NET MVC!";

        return View();
    }       

    public ActionResult GetAndDisplayEmployee()
    {
        return View();
    }

    [HttpPost]
    public ActionResult GetAndDisplayEmployee(int empid)
    {            
        return View(_employeeTask.GetEmployeeModelFromService(empid));            
    }
}

Global.asax.cs:

protected void Application_Start()
{
    AreaRegistration.RegisterAllAreas();
    RegisterGlobalFilters(GlobalFilters.Filters);
    RegisterRoutes(RouteTable.Routes);
    var container = new UnityContainer();
    container.RegisterType<IEmployeeModelMap, EmployeeModelMap>();
    container.RegisterType<IEmployeeService, EmployeeService>();
    container.RegisterType<IEmployeeTask, EmployeeTask>();
    container.RegisterType<IEmployee, Employee>();
    DependencyResolver.SetResolver(new UnityDependencyResolver(container));
}

Unity 依赖解析器:

 public class UnityDependencyResolver : IDependencyResolver
 {
     readonly IUnityContainer _container;
     public UnityDependencyResolver(IUnityContainer container)
     {
         this._container = container;
     }
     public object GetService(Type serviceType)
     {
         try
         {
             return _container.Resolve(serviceType);
         }
         catch
         {
             return null;
         }
     }
     public IEnumerable<object> GetServices(Type serviceType)
     {
         try
         {
             return _container.ResolveAll(serviceType);
         }
         catch
         {
             return new List<object>();
         }
     }
 }

员工任务类:

 public class EmployeeTask: IEmployeeTask
 {        
     IEmployeeService _employeeService;        
     IEmployeeModelMap _employeeModelMap;

     public EmployeeTask(IEmployeeService employeeService, IEmployeeModelMap employeeModelMap)
     {
         _employeeService = employeeService;
         _employeeModelMap = employeeModelMap;
     }

     public EmployeeViewModel GetEmployeeModelFromService(int empId)
     {
         return _employeeModelMap.ToModel(_employeeService.GetEmployeeFromEntities(empId));
     }
}

现在,我使用了 unity 2.0 应用程序块。尝试使用统一解决控制器的依赖关系而不使用自定义控制器工厂。 我遇到了以下错误。

当前类型 DataProviderInfrastructure.IEmployeeTask 是一个 接口,无法构造。您是否缺少类型映射?

【问题讨论】:

    标签: asp.net-mvc-3 dependency-injection unity-container ioc-container


    【解决方案1】:

    我不使用 Unity,但我的猜测是它会尝试使用您尝试解决依赖关系的无参数构造函数。创建这个构造函数是非常非常错误的。首先 - 它违背了依赖注入的目的,其次 - 你在里面创建新容器 - 这将是空的,因此它显然无法解决任何依赖关系。尝试从您的代码中删除它:

    public HomeController()
    {
        _employeeTask = new UnityContainer().Resolve<IEmployeeTask>();
    }
    

    【讨论】:

    • 为什么这被否决了?当我使用提供的代码拼凑一个快速应用程序时,它运行良好(并且它从未遇到无参数构造函数)。当我强迫它使用无参数构造函数时,它爆炸了,因为(正如 Lukas 已经说过的)控制器中的容器实例与 global.asax.cs 中的容器实例不同(所有依赖项都在其中注册)。如果删除无参数构造函数不能解决问题,则可能是我们没有看到导致问题的原因。
    • Unity会选择参数数量最多的构造函数,如果有其他选择则不会选择默认构造函数。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-04-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-07-05
    • 1970-01-01
    相关资源
    最近更新 更多