2016-09-18 72 views
-1

我想在我正在学习的项目中使用Unity作为IoC容器。我有一个分层应用程序,UI-> Service-> Logic-> DataAccess。Unity容器无法解析我的课

这是一个在UI端的MVC应用程序。

在我的控制,我有一个构造函数:

public HomeController() 
{ 
    _container = new UnityContainer(); 
    _container.RegisterType<IUserService, UserService>(); 
    _container.RegisterType<IUserLogic, UserLogic>(); 
} 

然后我尝试使用IService在我的方法之一:

var service = _container.Resolve<IUserService>(); 
ReplyDto reply = service.Login(model.Email, model.Password); 

但后来得到这个错误:

Resolution of the dependency failed, type = "Services.IUserService", name = "(none)".

我不知道为什么这么说。我可能有MVC和构造函数的问题吗? Resolve行上的断点显示_container确实有我尝试解决的接口。

我UserService类有这样的构造:

private IUserLogic _userlogic; 

public UserService(IUserLogic logic) 
{ 
    _userlogic = logic; 
} 

逻辑层类的定义是这样的:

public class UserLogic : IUserLogic 
{ 
    public ILog _logger; 
    public IData _data; 

    public UserLogic(IData data, ILog logger) 
    { 
     _data = data; 
     _logger = logger; 
    } 

我仍然在通过所有传播的IoC拍打下来的过程层。

最后,数据访问层被定义为:

public class Data :IData 
{ 
    Log _logger = new Log(); 
    MyEntities entities; 
    public Data() 
    { 
     entities = new MyEntities(); 
     var instance = System.Data.Entity.SqlServer.SqlProviderServices.Instance; 
    } 

我_container具有参照IUserLogic接口和其中使用的具体类。

+0

团结有什么错误很默认的痕迹......既然你没有表现出[MCVE]人们不得不猜测'UserLogic'具有Unity无法使用的构造函数(或者由于缺少依赖或非接口参数)。 –

+0

谢谢@Alexei - 我会研究你所指的。并在逻辑中发布我正在做的事情。 – Craig

+0

@AlexeiLevenkov - 我已经为这个问题的所有图层添加了构造函数。该错误是否表明在尝试解析Service类时,它在下面的构造函数之一上失败了? – Craig

回答

1

UserLogic(IData data, ILog logger) - 既不IData也不ILog挂号集装箱所示 - 因此,如果代码是完全一样,你在后拥有它之所以当unity试图将参数传递给UserService(IUserLogic)构造函数时,IUserLogic无法解析。

修复:注册所有依赖关系(递归)

为了实现这一目标考虑:

  • 确保类型不依赖具有构造不带参数
  • 寄存器的实例,而不是类型 - 是否适合你的系统
  • 使构造函数依赖于具体类型(因为默认情况下所有具体类型都注册为Unity) - 不可测试的选择...
  • 提供所有非接口/非类变量参数,如int/stringHow resolve a dependency with unity passing arguments in the constructor?
+0

完美。这是解决方案。但现在我不确定我的Container应该放在哪里。将它从控制器中移出听起来像是正确的事情(否则所有控制器都需要创建一个容器)。听起来它不应该在Global.ascx中,即使它是,我也不能引用它。 – Craig

+0

@Craig这里是一个指南 - http://weblogs.asp.net/shijuvarghese/asp-net-mvc-tip-dependency-injection-with-unity-application-block(它有点旧,但基本仍然是事实上,如bbonch的回答所示,控制器工厂的注册现在更简单了) –

1

你应该在Global.asax.cs中登记容器

public class Global : HttpApplication 
    { 
     private void Application_Start(object sender, EventArgs e) 
     { 
      IUnityContainer container = new UnityContainer(); 
      container.RegisterType<IUserService, UserService>(); 
      container.RegisterType<IUserLogic, UserLogic>(); 

      UnityDependencyResolver dependencyResolver = new UnityDependencyResolver(container); 
      GlobalConfiguration.Configuration.DependencyResolver = dependencyResolver; 
      DependencyResolver.SetResolver(dependencyResolver); 
     } 
    } 
+0

谢谢。会做出改变。我仍然可以从我的控制器中引用“容器”吗?和所有其他控制器? – Craig

+1

虽然对于一般的程序组织有很好的建议,但这与问题无关 - 作为评论指向您的建议的许多示例中的一个会很好。 –

+0

现在我的Global.asax文件需要参考我所有的图层。是对的吗? – Craig