Dear All,
Scenario:
WPF: contains a 3d viewport and some images with a interface implemented to access the information in WinForms. It is a usercontrol generating "*.dll" which is used in winforms.
WinForms: Has ElementHost which adds the WPF usercontrol and manipulates data.
Problem: I am having a memory leak problem.
public void Dispose(){
if (elementHost != null)
{
elementHost.Child = null;
elementHost.Dispose();
elementHost.Parent = null;
elementHost = null;
}
pluginService.AvailablePlugins.Clear();
if (dll != null)
{
if (File.Exists(dll))
{
try { File.Delete(dll); }
catch (Exception e) { MessageBox.Show(e.Message); }
}
}
}
Update:
Plugin Service: Gets the information of the WPF to WInForms
Plugin Service Class:
class PluginService : IPluginHost
{
private Types.AvailablePlugins colAvailablePlugins = new Types.AvailablePlugins();
public Types.AvailablePlugins AvailablePlugins
{
get { return colAvailablePlugins; }
set { colAvailablePlugins = value; }
}
public void AddPlugin(string filePath)
{
try
{
Assembly pluginAssembly = Assembly.LoadFrom(filePath);
foreach (Type pluginType in pluginAssembly.GetTypes())
{
try
{
if (pluginType.IsPublic)
{
if (!pluginType.IsAbstract)
{
Type typeInterface = pluginType.GetInterface("PluginInterface.Iplugin", true);
if (typeInterface != null)
{
Types.AvailablePlugin newPlugin = new Types.AvailablePlugin();
newPlugin.AssemblyPath = filePath;
newPlugin.Instance = (IPlugin)Activator.CreateInstance(pluginAssembly.GetType(pluginType.ToString()));
newPlugin.Instance.Host = this;
this.colAvailablePlugins.Add(newPlugin);
newPlugin = null;
}
typeInterface = null;
}
}
}
catch (Exception)
{
continue;
}
}
pluginAssembly = null;
}
catch (Exception)
{
}
}
public void Feedback(string Feedback, IPlugin Plugin) { }
}
namespace Types
{
public class AvailablePlugins : System.Collections.CollectionBase
{
public void Add(Types.AvailablePlugin pluginToAdd)
{
if (pluginToAdd != null)
this.List.Add(pluginToAdd);
}
}
public class AvailablePlugin
{
private IPlugin myInstance = null;
private string myAssemblyPath = "";
public IPlugin Instance
{
get { return myInstance; }
set { myInstance = value; }
}
public string AssemblyPath
{
get { return myAssemblyPath; }
set { myAssemblyPath = value; }
}
}
}
}
[Interface]Plugin
namespace PluginInterface
{
public interface IPlugin
{
IPluginHost Host { get; set; }
/// <summary>
/// Gets the WPF usercontrol
/// </summary>
UserControl MainInterface { get; }
/// <summary>
/// Gets the viewport of the 3D object.
/// </summary>
Viewport3D MainViewport { get; }
/// <summary>
/// Gets the backgroud image.
/// </summary>
Image BackImage { get; }
/// <summary>
/// Gets the mask image.
/// </summary>
Image MaskImage { get; }
/// <summary>
///
/// </summary>
Image ActiveImage { get; }
Image ShadowImage { get; }
BitmapImage BackBitmap { get; }
BitmapImage MaskBitmap { get; }
BitmapImage ActiveBitmap { get; }
BitmapImage ShadowBitmap { get; }
BitmapImage ViewportBitmap();
ImageBrush ImgBrush { get; }
string CurrentImage { get; set; }
BitmapImage GetBitmapImage { get; set; }
}
public interface IPluginHost
{
void Feedback(string Feedback, IPlugin Plugin);
}
}
[Update]
After looking into the help sites that you all suggested i wrote my code
This is the class inheriting MarshalByRefObject.
[Serializable]
public class RemoteLoader : MarshalByRefObject, IPluginHost
{
private Types.AvailablePlugins colAvailablePlugins = new Types.AvailablePlugins();
public Types.AvailablePlugins AvailablePlugins
{
get { return colAvailablePlugins; }
set { colAvailablePlugins = value; }
}
public void LoadAndExecute(string assemblyName)
{
Assembly pluginAassembly = Assembly.LoadFrom(assemblyName);
foreach (Type pluginType in pluginAassembly.GetTypes())
{
try
{
if (pluginType.IsPublic)
{
if (!pluginType.IsAbstract)
{
Type typeInterface = pluginType.GetInterface("PluginInterface.Iplugin", true);
if (typeInterface != null)
{
Types.AvailablePlugin newPlugin = new Types.AvailablePlugin();
newPlugin.AssemblyPath = assemblyName;
newPlugin.Instance = (IPlugin)Activator.CreateInstance(pluginAassembly.GetType(pluginType.ToString()));
newPlugin.Instance.Host = this;
this.colAvailablePlugins.Add(newPlugin);
newPlugin = null;
}
typeInterface = null;
}
}
}
catch (Exception)
{
continue;
}
}
pluginAassembly = null;
}
public void Feedback(string Feedback, IPlugin Plugin) { }
}
The other two supporting class are
namespace Types
{
[Serializable]
public class AvailablePlugins : System.Collections.CollectionBase
{
public void Add(Types.AvailablePlugin pluginToAdd)
{
if (pluginToAdd != null)
this.List.Add(pluginToAdd);
}
}
[Serializable]
public class AvailablePlugin
{
private IPlugin myInstance = null;
private string myAssemblyPath = "";
public IPlugin Instance
{
get { return myInstance; }
set { myInstance = value; }
}
public string AssemblyPath
{
get { return myAssemblyPath; }
set { myAssemblyPath = value; }
}
}
}
After i ran the code, it gave an error that the class is not serialized so i added it.
But after adding it, it still refers that the WPF usercontrol is not serialized, but i have added it there also.
[Serializable]
public partial class UserControl1 : UserControl, IPlugin
{
public UserControl1()
{
InitializeComponent();
}
DO you think i am doing something wrong?
Is there a solution in which i donot have to update my WPF usercontrol
Can anyone give suggestions