I have a host WinForm application extended with UserControls. Composition and instantiati开发者_如何学Goon work great on initial startup. When I close the user control, I want to assume that it should be Disposed. However, this causes a problem when I want to show the user control again.
What I want to do is return the user control to it's original state after I ensure the object has Disposed of any resources.
Here is one of the extension user controls:
[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 does all the discovery and composition work, providing a method to request a specific module:
// 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;
}
Now, when we find the module, assigning module.Value
causes the UserControl to be initialized - the constructor is called.
When the UserControl is closed and disposed, how can I return the module to this initial state?
I think your issue is that you are setting Module
to module.Value
, so you are instantiating the actual IUserModule
through the Lazy<IUserModule, IQueryMetadata>
instance. If you don't need it until later on, why no set Module
to the Lazy<IUserModule, IQueryMetadata>
instance instead, and then create an instance of it when you need it.
The other thing you may need to consider is lifetime of the part. Unless you are recomposing your Modules
collection, you'll only have one instance of the IUserModule
because it is created and instantiated through the Lazy<,>
instance. What you may want to consider is using an ExportFactory<IUserModule, IQueryMetadata>
to spin up a new instance each time instead.
ExportFactory
is not part of .NET 4.0 (it made into Silverlight, but not the full .NET 4.0 BCL. Glenn Block released a version of it for .NET 4, which you can get here.
精彩评论