我有一个主机WinForm应用程序扩展了UserControls。组合和实例化在初始启动时非常有效。当我关闭用户控件时,我想假设它应该是dispose。但是,当我想再次显示用户控件时,这会导致一个问题。
我想做的是返回用户控制到它的原始状态后,我确保对象已处置的任何资源。
下面是一个扩展用户控件:
[ExportMetadata ( "ModuleName", "ContactManager" )]
[Export ( typeof ( IUserModule ) )]
partial class ucxContactManager : IUserModule
{
#region Fields
// Fields
readonly string moduleName = "ContactManager";
readonly string moduleDescription = "Contact Manager Extension Module";
// called from ucxContactManager constructor
void InitializeUserModule ( )
{
Closing += ( o, e ) => Dispose ( );
uxCloseContactForm.Click += ( o, e ) => Closing ( this, null );
}
// IUserModule Members
public event EventHandler<EventArgs> Closing = delegate { };
}
CompositionController完成所有的发现和组合工作,提供一个方法来请求一个特定的模块:
// Lazily import all IUserModule interfaces
[ImportMany ( typeof ( IUserModule ), AllowRecomposition = true )]
public IEnumerable<Lazy<IUserModule, IQueryMetadata>> Modules { get; set; }
public bool TryGetModule ( string ModuleName, out IUserModule Module )
{
var module = Modules.Where ( m => m.Metadata.ModuleName == ModuleName )
.Select ( m => m )
.FirstOrDefault ( );
if (module != null)
{ Module = module.Value; }
else
{ Module = null; }
return Module != null;
}
现在,当我们找到模块,分配module.Value
导致UserControl被初始化-构造函数被调用。
当UserControl被关闭和处置时,我如何将模块返回到这个初始状态?
我认为您的问题是您将Module
设置为module.Value
,因此您正在通过Lazy<IUserModule, IQueryMetadata>
实例实例化实际的IUserModule
。如果您稍后才需要它,为什么不将Module
设置为Lazy<IUserModule, IQueryMetadata>
实例,然后在需要时创建它的实例呢?
您可能需要考虑的另一件事是部件的寿命。除非重新组合Modules
集合,否则只有一个IUserModule
实例,因为它是通过Lazy<,>
实例创建和实例化的。您可能想要考虑的是每次使用ExportFactory<IUserModule, IQueryMetadata>
来启动一个新实例。
ExportFactory
不是。net 4.0的一部分(它被纳入了Silverlight,但不是完整的。net 4.0 BCL)。Glenn Block为。net 4发布了一个版本,你可以点击这里获取。