开发者

Extending with UserControls: How do I return the composable part to initial state?

开发者 https://www.devze.com 2023-03-19 17:53 出处:网络
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

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.

0

精彩评论

暂无评论...
验证码 换一张
取 消