Autofac子依赖链注册问题如何构造AutoFacContainerBuilder,让我的子依赖能够正确解析(假设接口有多个具体实现)?默认注册/解析将不起作用,因为我有多个子依赖项的具体实现,并且子依赖项解析依赖于主对象的解析。在所有情况下,我更喜欢使用构造函数注入。脚本例如,假设我需要打印一张收据,所以我创建了一个名为IReceipt的接口和一个名为PrintReceipt()的方法。但是我需要打印3种类型的收据标准收据礼品收据电子邮件收据所有收据类型都有不同的格式,电子邮件收据根本不打印而是通过电子邮件发送。所以我希望我的IReceipt能够依赖格式化程序和处理器。假设我使用Process()方法创建了一个IProcessor,它可以是打印机处理器,也可以是邮件处理器(打印机处理器负责打印机通信,邮件处理器负责与SMTP服务器通信)。此外,我创建了一个IFormatter,它可以将输入提供给处理器对象,格式化为标准收据或礼品收据,甚至是电子邮件收据的HTML。因此,IRecipept的任何具体实现的构造函数现在都需要两个依赖项——IFormatter和IProcessor。现在,根据根的构成,我需要决定是否要为标准收据、礼品收据或电子邮件收据处理IReceipt。我想调用传递必要参数的容器Resolve()方法,以便它解析正确的IReceipt。另外,我希望已注册的ContainerBuilder知道,如果我尝试解析IReceipt标准收据的具体实现,它需要使用正确的标准收据IFormatter解析子依赖项,并更正标准收据IProcessor。礼品收据计划和电子邮件收据计划也是如此。概括因此-在所有这一切中-我的问题是-我如何构造ContainerBuilder以便在设计时定义子依赖项,并且对Resolve()的单个调用将正确识别所需的具体实现?我不是在寻找与打印机对话或发布HTML的解决方案。此问题仅针对Autofac注册和解决方法。在不同的客户端上,我使用了使用CastleWindsor的精确策略,但我当前的客户端使用的是Autofac。好的,所以我想出了一种方法来进行子依赖关系链接。同样,最好为每个根复合对象调用一次resolve并让所有子依赖项满足整个链。不打算就最佳实践进行宗教辩论——是否应实施工厂方法、服务定位器等。我故意遗漏了IoC范围,因为它不是我最初问题的主题。这个人为的例子没有实现电子邮件或打印机功能,但现在已被删除。重点是展示如何预定义整个依赖链。现在,自动化单元测试将更容易实施。密码主机计划usingSystem;使用System.Collections.Generic;使用Autofac;namespaceMyAutoFacTest{classProgram{staticvoidMain(string[]args){//创建IOC引擎和容器varbuilder=newAutofac.ContainerBuilder();Autofac.IContainer容器;//创建依赖链注册builder.RegisterType().Named("MyDefaultPrinter");builder.RegisterType().Named("PrinterProcessor").WithParameter(Autofac.Core.ResolvedParameter.ForNamed("我的默认打印机"));builder.RegisterType().Named("EmailProcessor");builder.RegisterType().Named("StandardReceiptFormatter");builder.RegisterType().Named("GiftReceiptFormatter");builder.RegisterType().Named("EmailReceiptFormatter");builder.RegisterType().Named("StandardReceipt").WithParameter(Autofac.Core.ResolvedParameter.ForNamed("PrinterProcessor")).WithParameter(Autofac.Core.ResolvedParameter.ForNamed("StandardReceiptFormatter"));builder.RegisterType().Named("GiftReceipt").WithParameter(Autofac.Core.ResolvedParameter.ForNamed("PrinterProcessor")).WithParameter(Autofac.Core.ResolvedParameter.ForNamed("GiftReceiptFormatter"));builder.RegisterType().Named("EmailReceipt").WithParameter(Autofac.Core.ResolvedParameter.ForNamed("EmailProcessor")).WithParameter(Autofac.Core.ResolvedParameter.ForNamed("EmailReceiptFormatter"));//编译AUTOFAC注册容器=builder.Build();//设置初始化内容-作为外部系统集成的一部分通常会发生的事情intsomeBogusDatabaseIdentifier=1;varstandardReceipt=container.ResolveNamed("StandardReceipt");standardReceipt.PrintReceipt(someBogusDatabaseIdentifier);vargiftReceipt=container.ResolveNamed("GiftReceipt.");giftReceiptPrintReceipt(someBogusDatabaseIdentifier);varemailReceipt=container.ResolveNamed("EmailReceipt");emailReceipt.PrintReceipt(someBogusDatabaseIdentifier);Console.ReadLine();}}}接口IPrinternamespaceMyAutoFacTest{publicinterfaceIPrinter{voidPrint();}}IReceipt命名空间MyAutoFacTest{公共接口IReceipt{voidPrintReceipt(intid);}}IProcessor命名空间MyAutoFacTest{公共接口IProcessor{voidProcess(stringformattedString);}}IFormatter命名空间MyAutoFacTest{publicinterfaceIFormatter{stringGetFormattedString(intid);}}工具实施将首先显示叶依赖…打印机usingSystem;namespaceMyAutoFacTest{publicclassPrinter:IPrinter{publicvoidPrint(){Console.WriteLine("打印机正在打印");}}}打印机处理器usingSystem;命名空间MyAutoFacTest{publicclassPrinterProcessor:IProcessor{privateIPrinter_printer;公共PrinterProcessor(IPrinter打印机){this._printer=打印机;}publicvoidProcess(stringformattedString){Console.WriteLine("Printerprocessorsendingreceipttoprinter.");这个._printer.Print();}}}邮件处理器usingSystem;命名空间MyAutoFacTest{publicclassEmailProcessor:IProcessor{publicvoidProcess(stringformattedString){Console.WriteLine("EmailProcessorsendingoutaemailreceipt");}}}标准接收格式化程序命名空间MyAutoFacTest{publicclassStandardReceiptFormatter:IFormatter{publicstringGetFormattedString(intid){return"StandardReceiptFormatterformattedstring";}}}礼品收据格式化程序namespaceMyAutoFacTest{publicclassGiftReceiptFormatter:IFormatter{publicstringGetFormattedString(intid){return"GiftReceiptFormatterformattedstring";}}}电子邮件接收格式化程序namespaceMyAutoFacTest{publicclassEmailReceiptFormatter:IFormatter{publicstringGetFormattedString(intid){return"EmailReceiptFormatterformattedstring";}}}收集使用系统;namespaceMyAutoFacTest{publicclassReceipt:IReceipt{privateIFormatter_formatter;私有IProcessor_processor;公共收据(IFormatter格式化程序,IProcessor处理器){this._formatter=格式化程序;你s._processor=处理器;}publicReceipt(IFormatterformatter){this._formatter=formatter;}publicReceipt(IProcessorprocessor){this._processor=processor;}publicvoidPrintReceipt(intid){varformattedString=this._formatter.GetFormattedString(id);Console.WriteLine(格式化字符串);this._processor.Process(formattedString);}}}结论大多数与需要创建的对象相关的噪音都被捆绑到一个位置实际上,我可能会将Move注册到它自己的代码块(可能是一个静态类)。将噪音排除在函数类之外会产生专注于函数意图的漂亮干净的代码。所有电汇都是在此过程的早期进行的,现在已经消失了。尤其是看注册,我设计的例子有4层依赖。MainReceiptObjectProcessorandFormatterPrinter(仅用于打印机处理程序)(可能表明依赖于电子邮件服务器,但我认为该示例相当清楚)。通过使用Autofac.Core.ResolvedParameter,我们可以引用其他已注册的对象(按名称)。这将使注册时间很长,但持平。任何层次结构都表示(浅-如果这是一个词)仅作为父子关系,并且非常可重用。仅在根复合对象上调用Resolve-3个收据引擎(标准、礼品和电子邮件)。对于每个根复合对象,整个依赖链现在是可解析的。以上就是C#学习教程:Autofac子依赖链注册与分享。如果对你有用,需要进一步了解C#学习教程,希望大家多多关注。本文收集自网络,不代表立场。如涉及侵权,请点击右边联系管理员删除。如需转载请注明出处: