Update 09.08.2018
Unity正在开发here但我没有时间来测试它如何与ASP.NET Core框架配合使用 .
Update 15.03.2018
此解决方案针对在使用.NET Framework 4.5.2 NOT .NET Core Framework时将ASP.NET Core v1与Unity一起使用的特定问题 . 我不得不使用这个设置,因为我需要一些.Net 4.5.2 DLL,但对于任何重新开始的人我都不会推荐这种方法 . 此外,Unity还没有进一步开发(据我所知)所以我建议将Autofac框架用于新项目 . 有关如何执行此操作的详细信息,请参阅Post .
Intro
我正在使用ASP.NET和MVC构建Web应用程序 . 此应用程序依赖于某些服务(WCF服务,数据存储区服务等) . 现在为了保持良好和解耦,我想使用DI(Dependecy Injection)框架,特别是Unity .
Initial Research
我发现这个blog post但遗憾的是它不起作用 . 这个想法虽然很好 .
它基本上表示您不应将ServiceCollection中注册的所有服务注册到您自己的容器中,而应引用默认的ServiceProvider .
所以 . 如果需要解决某些问题,则调用默认的ServiceProvider,如果没有解析,则使用自定义UnityContainer解析类型 .
The Problems
MVC始终尝试使用默认的ServiceProvider解析Controller .
此外,我注意到即使控制器得到正确解析,我也永远不会"mix"依赖关系 . 现在,如果我想使用我的一个服务而且还要使用ASP的IOptions接口,则该类永远无法解析,因为这两个容器中没有一个具有两种类型的解析 .
What I need
所以回顾一下,我需要以下内容:
-
我不需要将ASP.NET依赖项复制到UnityContainer中的设置
-
可以解析我的MVC控制器的容器
-
可以解析"mixed"依赖关系的容器
EDIT:
所以问题是我如何才能实现这些要点?
Environment
project.json:
2 回答
经过一些研究后,我想出了以下解决方案来解决我的问题:
Use Unity with ASP
为了能够与ASP一起使用Unity,我需要一个自定义的IServiceProvider(ASP Documentation),所以我为IUnityContainer编写了一个包装器,看起来像这样
另外,我不得不改变我的Startup类中的ConfigureServices方法的签名:
对此:
现在我可以返回我的自定义IServiceProvider,它将被用来代替默认值 .
完整的ConfigureServices方法显示在底部的Wire up部分 .
Resolving Controllers
我找到了this blog post . 从中我了解到MVC使用IControllerActivator接口来处理Controller实例化 . 所以我写了我自己的,看起来像这样:
现在,如果激活了Controller类,它将使用我的UnityContainer进行实例化 . 因此我的UnityContainer必须知道如何解析任何控制器!
Next Problem: Use the default IServiceProvider
现在,如果我在ASP.NET中注册Mvc等服务,我通常会这样做:
现在,如果我使用UnityContainer,则无法解析所有MVC依赖项,因为它们未注册 . 所以我可以注册它们(比如AutoFac)或者我可以创建一个UnityContainerExtension . 我选择了扩展并提出以下两个条款:
UnityFallbackProviderExtension
UnityFallbackProviderStrategy :
现在,如果我的UnityContainer没有注册的东西,它只是询问默认的提供商 .
我从几篇不同的文章中学到了所有这些
MSDN Unity article
Auto-Mocking Unity Container Extension
Custom Object Factory Unity Extension
这种方法的好处是我现在也可以"mix"依赖 . 如果我需要来自ASP的任何服务和IOptions接口,我的UnityContainer将解析所有这些依赖项并将它们注入我的控制器!
唯一要记住的是,如果我使用任何自己的依赖项,我必须使用Unity注册我的Controller类,因为默认的IServiceProvider无法再解析我的控制器依赖项 .
Finally: Wire up
现在在我的项目中,我使用不同的服务(ASP选项,带选项的MVC) . 为了使它全部工作,我的ConfigureServices方法现在看起来像这样:
因为我在过去一周里学到了大部分关于DI的知识,所以我希望我没有打破任何大的主要/模式,如果是这样,请告诉我!
对于ASP.Net Core 2.0,2.1和Unity,Unity提供官方解决方案作为NuGet包的作者:NuGetPackage
这是带有示例的Git存储库:Git repo
用法非常简单(来自Git repo主页):
here是用于ASP.Net Core的Unity DI的示例 .
我在我的ASP.Net Core应用程序中使用此解决方案并且运行良好 .