2015-11-05 47 views
0

在Web API项目中使用Unity时,我以标准方式在UnityContainer中注册了一个对象。如何在.NET Web API中使用Unity进行解析

public static class UnityConfig { 
    public static void RegisterComponents() { 
     var container = new UnityContainer(); 
     GlobalConfiguration.Configuration.DependencyResolver = new UnityDependencyResolver(container); 

     container.RegisterType<IMyService, MyService>(); 
     ... 
    } 
} 

我解决这样我班的一个对象(这不是一个控制器,所以我不能使用构造函数注入):

var myService = (IMyService)GlobalConfiguration.Configuration.DependencyResolver 
        .GetService(typeof(IMyService)); 

是,正确的方法是什么?它看起来很笨重。是否有更简洁的方式来进行此调用,例如直接访问容器的Resolve<T>()方法?

(我可以在这里鸡蛋里挑骨头,但我是新来使用Unity使用Web API,并试图了解的最佳实践。)

+0

对于非控制器,为什么不直接将实例保持为静态(单例)并从那里访问? – vendettamit

+0

你从哪里调用代码?你说这是一个非控制器。这是一项服务吗?它在哪里使用? –

+0

此代码位于我创建的自定义属性中,这使事情变得复杂。我对Spock的答案感到满意(简而言之,我应该依赖依赖注入而不是直接调用DependencyResolver),但事实证明,Unity无法注入到属性中(参见[这里](http://stackoverflow.com/)问题/ 9677029/injecting-class-into-authentication-attribute-using-unity-2-and-mvc-3)and [here](http://stackoverflow.com/questions/6121050/mvc-3-unity-2 -inject-dependencies-into-a-filter)),所以我的选择是保持我的代码原样或实现一个自定义的FilterAttributeFilterProvider。 – Keith

回答

0

“那是正确的方式”?

一般来说,如果您使用正确的DI原则,答案是否。 您所做的是要求DependencyResolver解决服务IMyService。 这也被称为Hollywood Principal:不要调用容器;它会打电话给你。

这也是要求Unity容器解决IMyService的问题。 即 Container.Resolve

最好的方法是使用适当的构造函数注入,如果没有财产注射或某些指定的注入模式的 https://github.com/ninject/Ninject/wiki/Injection-Patterns

如果你的依赖,需要在很多类注射比通常更可能你也考虑使用Ambient Container。但这种情况不太可能。 What is the meaning of the word ambient in this comment from CommonServiceLocator?

另请注意,您的类使用了DependencyResolver,它使用了DI技术,即.Resolve,它在类的外面不可见。 这也意味着组件不能被重用,因为外部世界无法确定它在编译时需要什么DI。如果DI需求未注册,则可能导致运行时错误(如果依存尚未注册)。