-1

I am trying to create a plugin system for my application by defining a common interface and then loading the assemblies dynamically in the current App-domain through reflection. Here is the code for main application:

var asm = Assembly.Load(an);
var types = asm.GetTypes();
foreach (var type in types)
{
    if (type.GetInterface(typeof(IModule).ToString()) != null)
    {
        IModule module = null;
        try
        {
            module = asm.CreateInstance(type.ToString(), true) as IModule;
        }
        catch (Exception)
        {

        }
        if (module != null)
        {
            _modules.Add(module);//These objects implement plugin interface
        }

    }
}

Problem is that even though I am caching the IModule objects of the plugin at class level, it seems to be garbage collected. Here is the plugin code to demonstrate the problem:

internal class SamplePlugin : IModule
{
    public void Initialize() // IModule implementation
    {
        _timer = new System.Timers.Timer(1000);
        _timer.Enabled = true;
        _timer.Elapsed += TimerElapsed;
    }

    //This method never gets called
    void TimerElapsed(object sender, ElapsedEventArgs e)
    {
    }
} 

The initialize method gets called successfully when I call the initialize method on cached IModule objects. But the TimerElapsed method never gets called, suggesting that the object has been garbage collected by CLR.

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
Samarsh
  • 565
  • 5
  • 18
  • Where do you cache them? Perhaps that gets disposed/out of scope early. – Marcel N. Aug 10 '14 at 08:45
  • I am caching them at the class level (as a field) and the current class is a field of the Main class. So not sure why it is happening. Maybe the plugin assembly gets unloaded or something. – Samarsh Aug 10 '14 at 08:49
  • No, assemblies cannot get unloaded from the default domain. – Marcel N. Aug 10 '14 at 08:50
  • Please put more effort into formatting your code - look at the preview before you post, and ask yourself if that's how you'd want the post to look if you were reading it. – Jon Skeet Aug 10 '14 at 08:50
  • You may need to show more code. My guess is either timer gets out of scope, or disposed or the `SamplePlugin` instance itself GC'd – Sriram Sakthivel Aug 10 '14 at 08:59
  • Where is Initialize getting called? Also is _timer a field or a local variable? If it is local, try making it a field. – Mike Zboray Aug 10 '14 at 09:06
  • @JonSkeet Not sure what part of the code you are referring to. I just added the code and did Ctr + K to format it. And it looked OK to me in the preview. Must be a good reason to downvote I guess. – Samarsh Aug 10 '14 at 10:59
  • @SriramSakthivel _timer couldn't get out of scope as it is a field variable. The class might be but the reason is not clear. – Samarsh Aug 10 '14 at 11:04
  • @HarshMaurya: Look at the code *before* I edited it - the first piece of code is all the way over, so you have to scroll, completely pointlessly. It looks okay *now* because I fixed it for you, but I shouldn't have had to. It wasn't my downvote though... – Jon Skeet Aug 10 '14 at 11:23
  • @JonSkeet Will keep that in mind next time :) – Samarsh Aug 10 '14 at 11:41

1 Answers1

0

Solved the problem by caching the assembly objects as well. Don't know why it was needed.

Samarsh
  • 565
  • 5
  • 18