Winforms 如何在UserControls上使用依赖注入&;形式

Winforms 如何在UserControls上使用依赖注入&;形式,winforms,dependency-injection,castle-windsor,Winforms,Dependency Injection,Castle Windsor,遇到了一个知识缺口,离开WinForms太久了,不确定我是否为Castle Windsor做了正确的事情 在过去的5年里,我一直在开发ASP.Net应用程序(WebForms、MVC等)。我现在有一个项目,其中web界面还不是一个可行的解决方案。所以我们用WinForms来做 有了Asp.Net,我就可以设置Castle Windsor容器、CWC、静态类以及所有依赖项注入等 说到WinForms,我遇到了一些问题。显然,我无法实现与WebForms开发相同的依赖项注入规则 目前的执行情况: P

遇到了一个知识缺口,离开WinForms太久了,不确定我是否为Castle Windsor做了正确的事情

在过去的5年里,我一直在开发ASP.Net应用程序(WebForms、MVC等)。我现在有一个项目,其中web界面还不是一个可行的解决方案。所以我们用WinForms来做

有了Asp.Net,我就可以设置Castle Windsor容器、
CWC
、静态类以及所有依赖项注入等

说到WinForms,我遇到了一些问题。显然,我无法实现与WebForms开发相同的依赖项注入规则

目前的执行情况: Program.cs:

static void Main () {
    Initialize();

    Application.EnableVisualStyles();
    Application.SetCompatibleTextRenderingDefault( false );

    var form = CWC.Resolve<frmMain>();
    Application.Run( form );

}

public static void Initialize ( string log4netPath = null ) {
    var container = new WindsorContainer();

    container.Kernel.ComponentModelCreated += ( s => {
        if ( s.LifestyleType == LifestyleType.Undefined )
            s.LifestyleType = LifestyleType.PerWebRequest;
    } );

    container.Install(
        new CoreManagerInstaller() , 
        new DomainInstaller() ,
        new RepositoryInstaller() ,
        new ServiceInstaller()
    );

    //Installer for MVC framework -- Must be done after other installers on its own.
    container.Install( new AppInstaller() );

    if ( log4netPath != null ) {
        //container.AddFacility( new LoggingFacility( LoggerImplementation.Log4net , log4netPath ) );
    }

    CWC.Init( container );
}
但是在这个设计中,
ServerRepository
从未被实例化。我必须手动调用
CWC.Resolve()
,以便属性具有所需的信息

是否有一种方法可以使ServerRepository自动(神奇地)填充容器中的对象数据


已尝试执行公共ClientInformation控件(IServerRepository serverRepo){},但分配没有持续通过构造函数,因此当触发Control.Load事件时,ServerRepository属性已清空。

usercontrols的问题是它们无法通过DI框架(DIF)解决

您尚未发布winform的代码,但我假设设计器代码如下所示:

private void InitializeComponent()
{
    this.ClientInformationControl1 = new ClientInformationControl();
    [...]
}
这是因为您可能将用户控件拖到表单上,因此DIF不知道它

有多种方法可以解决此问题:

1:不要使用设计器添加用户控件,而是注册它们并让DIF为您解析它们。您可以通过将它们作为属性添加到构造函数参数中来实现这一点,或者在需要时解析usercontrol


2:为已解析的父级(表单)提供IServerRepository依赖项。但是,您必须手动将IServerRepository连接到usercontrol…

我现在有一个项目,其中web界面还不是一个可行的解决方案。因此,我们正在使用WinForms进行此操作。
-只是一个旁注。winforms不建议用于任何新项目。这是一项非常古老的技术,已经被更现代、可扩展、可定制、更快、独立于分辨率、基于向量、硬件加速、美观、基于XAML的技术所取代(这些技术也比winforms更接近Web范例,并且支持更干净的模式)。你真的应该重新考虑你的决定。我不想用这个评论冒犯任何人。谢谢你的非建设性评论。在不同的框架中这样做是有原因的,而这恰好是他们的基础设施需要并且能够处理的原因。我还没有达到清除设计器代码,只使用设计器中我需要的代码的状态。因为我的其他DLL项目包含安装程序,所以我不必做一个大规模的DIF注册表,有没有更简单的方法来做这个“自动注册表”?在MVC中,我做了类似于
container.Register(Classes.fromthissembly().BasedOn().LifestyleTransient())的事情
以获取所有控制器以进行解析。WinForms会有类似的方法吗?好吧,您仍然可以使用
类。FromThisAssembly()
来注册所有内容。我相信System.Windows.controls.Control中的所有用户控件都是固有的,因此您可以基于此注册它们。但问题是,在MVC中,控制器通过ControllerFactory工厂的约定得到解决。Winforms没有类似的东西,所以如果我为这些控件提供一个派生控件类,我可以做一些类似于IController的事情,对吗?假设应用程序中使用的所有控件继承了
IAppControl
,或
AppControl
的公共属性值。那么我的DIF注册表将是
Classes.FromThisAssembly().BasedOn
,或者类的等效项?基本上是的。这就是我提到的原因,我认为所有用户控件都源自
System.Windows.Controls.Control
,所以您可以尝试使用它。但是,即使您注册了它们,也不能像往常一样将它们拖放到表单上,因为这只会创建对象的新实例,而不是解析它。感谢您的教育和帮助。
public partial class ClientInformationControl : UserControl {
        public IServerRepository ServerRepository { get; set; }

        private void ClientInformation_Load ( object sender , EventArgs e ) {
            var servers = ServerRepository.Find().Select( s => new { Key=s.Id , Value=s.Name } );
            cboServers.Items.AddRange( servers.ToArray() );

        }
}
private void InitializeComponent()
{
    this.ClientInformationControl1 = new ClientInformationControl();
    [...]
}