遇到知识差距,离开WinForms已经很久了,不确定我是否正在为温莎城堡做这件事。
在过去的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 );
}
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中,我会删除Property签名并开始在我需要的事件/方法中使用。
因此:
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>()
才能让财产获得有需要的信息。
有没有办法让ServerRepository自动(自动地)用容器中的对象数据填充?
尝试执行public ClientInformationControl(IServerRepository serverRepo){}
但是赋值没有持续超过构造函数,因此当触发Control.Load事件时,ServerRepository属性已被清空。
答案 0 :(得分:1)
usercontrols的问题在于它们没有被DI框架(DIF)解决。
您尚未发布winform的代码,但我认为设计器代码看起来像这样:
private void InitializeComponent()
{
this.ClientInformationControl1 = new ClientInformationControl();
[...]
}
这是因为您可能将用户控件拖到表单上,因此DIF不知道它。
有多种方法可以解决这个问题:
1:不要使用设计器来添加用户控件,而是注册它们并让DIF为您解决它们。您可以通过将它们作为属性添加到constuctor参数中来执行此操作,或者在需要时解析用户控件。
2:为已解析的父级(表单)提供IServerRepository依赖项。但是你必须手动将IServerRepository连接到用户控件......