如何在UserControls和应用程序上使用依赖注入形式 [英] How to Use Dependency Injection on UserControls & Forms

查看:66
本文介绍了如何在UserControls和应用程序上使用依赖注入形式的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

遇到知识鸿沟,已经离开WinForms很久了,不确定我是否正确地为温莎城堡做这件事。

Running into a knowledge gap, been out of WinForms for so long, unsure if i am doing this correctly for Castle Windsor.

在过去的5年中,我有开发ASP.Net应用程序(WebForm,MVC等)。我现在有一个项目,其中Web界面不是可行的解决方案。因此,我们正在使用WinForms。

For the last 5 years i have developing ASP.Net applications (WebForms, MVC, etc). I now have a project where a web interface is not a viable solution, yet. So we are doing it with WinForms.

使用Asp.Net,我只需设置Castle Windsor Container, CWC ,静态类和其他所有东西都可以照顾到依赖注入等。

With Asp.Net, i would have just set up the Castle Windsor Container, CWC, static class and everything would have taken care of itself for Dependency Injections, etc.

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

I am having some issues when it comes to WinForms. I evidently cant implement the same rules for Dependency Injection that i did for the WebForms developments.

Program.cs:

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 );
}

AppInstaller:

AppInstaller:

public class AppInstaller : IWindsorInstaller {

    #region IWindsorInstaller Members

    public void Install ( IWindsorContainer container , IConfigurationStore store ) {
        container.Register(
            Classes.FromThisAssembly()
                .BasedOn<CIMForm>().LifestyleTransient() ,
            Classes.FromThisAssembly()
                .BasedOn<CIMTabControl>().LifestyleTransient() ,
            Classes.FromThisAssembly()
                .BasedOn<CIMTabPage>().LifestyleTransient() ,
            Classes.FromThisAssembly()
                .BasedOn<UserControl>().LifestyleTransient() );
    }

    #endregion
}

全部

有问题的孩子是UserControl,我正在尝试从其他库引用接口。在WebForms中,我会删除属性签名,并开始在需要的事件/方法中使用它。

The problem child is the UserControl i am trying to reference Interfaces form other libraries. In WebForms i would have just dropped the Property signature and started using in the Event/Methods i needed it.

因此:

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() );

        }
}

但是 ServerRepository 从未在此设计中实例化。我必须手动调用 CWC.Resolve< IServerRepository>()才能使该属性具有所需的信息。

But ServerRepository never gets instantiated in this design. I have to manually call CWC.Resolve<IServerRepository>() in order for the property to have the information in need.

有没有办法使ServerRepository自动(自动)用容器中的对象数据填充?

Is there a way to make it so that ServerRepository is automatically (auto-magically) filled with the object data from the container?

尝试做 public ClientInformationControl(IServerRepository serverRepo){} ,但是分配没有在构造函数中保留,因此当触发Control.Load事件时,ServerRepository属性已被清空。

Tried doing public ClientInformationControl(IServerRepository serverRepo){} but the assignment did not persist past the constructor, so when the Control.Load event was triggered the ServerRepository Property has been emptied out.

推荐答案

用户控件的问题在于DI框架(DIF)无法解决它们。

The problem with usercontrols is that they do no get resolved by the DI framework (DIF).

您尚未发布Winform的代码,但是我认为设计器代码如下所示:

You havent posted the code of your winform, but I assume the designer code looks something like this:

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

这是因为您可能拖了用户控制该表单,因此DIF对此一无所知。

This is because you probably dragged the user control onto the form, so the DIF does not know about it.

有多种解决方法:

1:不要使用设计器添加用户控件,而是注册它们,然后让DIF为您解析它们。您可以通过将其作为属性添加到构造函数参数中来执行此操作,也可以在需要时解析用户控件。

1: Don't use the designer to add usercontrols, but register them and let the DIF resolve them for you. You can do this by adding them to the constuctor parameters, as property, or resolve the usercontrol whenever you need it.

2:提供要解析的父级(形式为)的IServerRepository依赖项。但是之后,您必须手动将IServerRepository连接到用户控件中,然后通过...

2: Give the parent that is resolved (the form) a IServerRepository dependency. But then you'll have to manually wire the IServerRepository into the usercontrol tho...

这篇关于如何在UserControls和应用程序上使用依赖注入形式的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆