我正在将依赖注入(inject)框架引入现有的 WebForms 应用程序(使用 CaSTLe Windsor)。
我对 DI 有很深的经验,并且倾向于非常强烈地支持构造函数注入(inject)而不是 setter 注入(inject)。如果您熟悉 Webforms,就会知道 ASP.Net 框架处理页面和控件对象的构造,从而使真正的构造函数注入(inject)成为不可能。
我目前的解决方案是在 Global.asax 的 Application_Start 事件中注册容器,并将容器作为公共(public)静态变量保存在 Global 中。然后,我只需直接在页面中解决我需要的每项服务,或在我需要它们时进行控制。所以在每个页面的顶部,我最终得到这样的代码:
private readonly IMyService _exposureManager = Global.IoC.Resolve<IMyService>();
private readonly IMyOtherService _tenCustomersExposureManager = Global.IoC.Resolve<IMyOtherService>();
显然,我不喜欢让所有这些对容器的引用分散在我的应用程序中,或者让我的页面/控件依赖关系不明确,但我一直无法找到更好的方法。
对于将 DI 与 Webforms 结合使用是否有更优雅的解决方案?
最佳答案
我同意@DarinDimitrov 的观点,MVP 是一个有趣的选择。然而,在使用遗留应用程序时,将现有页面重写为 MVP 模式是一项艰巨的工作。在这种情况下,最好从您已经在做的服务定位器模式开始(但仅在您的 UI 类中)。但是,请改变一件事。不要将所选的 DI 容器暴露给应用程序,因为我希望您使用 Global.IoC属性(property)。
相反,创建一个静态的 Resolve<T> Global 上的方法类(class)。这完全隐藏了容器并允许您交换实现而无需更改网页中的任何内容。当您这样做时,按照@Wiktor 的建议使用 Common Service Locator 没有任何优势。 Common Service Locator 只是对不必抽象的东西的另一种抽象(因为您已经使用 Global.Resolve<T> 抽象掉了容器)。
不幸的是,对于 Web 表单,确实没有任何好的方法可以做到这一点。对于 Simple Injector ,我写了一个 integration guide for Web Forms基本上描述了 Global.Resolve<T> 的使用方法,还展示了一种测试是否可以创建页面类的方法。该指南也可用于其他 DI 容器。
顺便说一句,请记住,对于温莎城堡,您请求的所有内容都必须明确发布(Register Resolve Release pattern)。这有点令人讨厌(IMO),并且与其他容器的工作方式不同,如果您没有正确执行此操作,可能会成为内存泄漏的来源。
最后一个音符。 It is possible to do constructor injection with Web Forms .好吧...有点,因为这将在 Form 之后使用反射调用重载的构造函数已使用默认构造函数创建,因此这会导致 Temporal Coupling .
关于c# - 网络表单和依赖注入(inject),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8947423/
我得到了一个包含嵌套链接的表单。编辑时链接字段为空的问题。这是我的表格:Editingkategori{:action=>'update',:id=>@konkurrancer.id})do|f|%>'Trackingurl',:style=>'width:500;'%>'Editkonkurrence'%>|我的konkurrencer模型:has_one:link我的链接模型:classLink我的konkurrancer编辑操作:defedit@konkurrancer=Konkurrancer.find(params[:id])@konkurrancer.link_attrib
我正在尝试修改当前依赖于定义为activeresource的gem:s.add_dependency"activeresource","~>3.0"为了让gem与Rails4一起工作,我需要扩展依赖关系以与activeresource的版本3或4一起工作。我不想简单地添加以下内容,因为它可能会在以后引起问题:s.add_dependency"activeresource",">=3.0"有没有办法指定可接受版本的列表?~>3.0还是~>4.0? 最佳答案 根据thedocumentation,如果你想要3到4之间的所有版本,你可以这
我收到这个错误:RuntimeError(自动加载常量Apps时检测到循环依赖当我使用多线程时。下面是我的代码。为什么会这样?我尝试多线程的原因是因为我正在编写一个HTML抓取应用程序。对Nokogiri::HTML(open())的调用是一个同步阻塞调用,需要1秒才能返回,我有100,000多个页面要访问,所以我试图运行多个线程来解决这个问题。有更好的方法吗?classToolsController0)app.website=array.join(',')putsapp.websiteelseapp.website="NONE"endapp.saveapps=Apps.order("
我有一个服务模型/表及其注册表。在表单中,我几乎拥有服务的所有字段,但我想在验证服务对象之前自动设置其中一些值。示例:--服务Controller#创建Action:defcreate@service=Service.new@service_form=ServiceFormObject.new(@service)@service_form.validate(params[:service_form_object])and@service_form.saverespond_with(@service_form,location:admin_services_path)end在验证@ser
如何在ruby中调用C#dll? 最佳答案 我能想到几种可能性:为您的DLL编写(或找人编写)一个COM包装器,如果它还没有,则使用Ruby的WIN32OLE库来调用它;看看RubyCLR,其中一位作者是JohnLam,他继续在Microsoft从事IronRuby方面的工作。(估计不会再维护了,可能不支持.Net2.0以上的版本);正如其他地方已经提到的,看看使用IronRuby,如果这是您的技术选择。有一个主题是here.请注意,最后一篇文章实际上来自JohnLam(看起来像是2009年3月),他似乎很自在地断言RubyCL
我想在Ruby中创建一个用于开发目的的极其简单的Web服务器(不,不想使用现成的解决方案)。代码如下:#!/usr/bin/rubyrequire'socket'server=TCPServer.new('127.0.0.1',8080)whileconnection=server.acceptheaders=[]length=0whileline=connection.getsheaders想法是从命令行运行这个脚本,提供另一个脚本,它将在其标准输入上获取请求,并在其标准输出上返回完整的响应。到目前为止一切顺利,但事实证明这真的很脆弱,因为它在第二个请求上中断并出现错误:/usr/b
我正在尝试在Ruby中复制Convert.ToBase64String()行为。这是我的C#代码:varsha1=newSHA1CryptoServiceProvider();varpasswordBytes=Encoding.UTF8.GetBytes("password");varpasswordHash=sha1.ComputeHash(passwordBytes);returnConvert.ToBase64String(passwordHash);//returns"W6ph5Mm5Pz8GgiULbPgzG37mj9g="当我在Ruby中尝试同样的事情时,我得到了相同sha
C#实现简易绘图工具一.引言实验目的:通过制作窗体应用程序(C#画图软件),熟悉基本的窗体设计过程以及控件设计,事件处理等,熟悉使用C#的winform窗体进行绘图的基本步骤,对于面向对象编程有更加深刻的体会.Tutorial任务设计一个具有基本功能的画图软件**·包括简单的新建文件,保存,重新绘图等功能**·实现一些基本图形的绘制,包括铅笔和基本形状等,学习橡皮工具的创建**·设计一个合理舒适的UI界面**注明:你可能需要先了解一些关于winform窗体应用程序绘图的基本知识,以及关于GDI+类和结构的知识二.实验环境Windows系统下的visualstudio2017C#窗体应用程序三.
网络编程套接字网络编程基础知识理解源`IP`地址和目的`IP`地址理解源MAC地址和目的MAC地址认识端口号理解端口号和进程ID理解源端口号和目的端口号认识`TCP`协议认识`UDP`协议网络字节序socket编程接口`sockaddr``UDP`网络程序服务器端代码逻辑:需要用到的接口服务器端代码`udp`客户端代码逻辑`udp`客户端代码`TCP`网络程序服务器代码逻辑多个版本服务器单进程版本多进程版本多线程版本线程池版本服务器端代码客户端代码逻辑客户端代码TCP协议通讯流程TCP协议的客户端/服务器程序流程三次握手(建立连接)数据传输四次挥手(断开连接)TCP和UDP对比网络编程基础知识
我今天看到了一个ruby代码片段。[1,2,3,4,5,6,7].inject(:+)=>28[1,2,3,4,5,6,7].inject(:*)=>5040这里的注入(inject)和之前看到的完全不一样,比如[1,2,3,4,5,6,7].inject{|sum,x|sum+x}请解释一下它是如何工作的? 最佳答案 没有魔法,符号(方法)只是可能的参数之一。这是来自文档:#enum.inject(initial,sym)=>obj#enum.inject(sym)=>obj#enum.inject(initial){|mem