0

I've put together an application that I plan on writing plugins for. In order to keep everything separate and make updating easy, I figured writing individual class libraries would be the best solution. The problem I'm running into is that my dll can't communicate with it's parent. Is this only one-way communication?

I dynamically load the dll at runtime and can tell it to do what I want it to do without any problems. The problem I encounter is after it's finished doing its work, I can't get it to signal the parent that it's finished. I don't want the parent to hang and wait for it, so I open a new thread in the dll to do the "work". I tried something as simple as passing a self reference to the dll when it's opened, but I get an access violation when I try to access something on the parent from the DLL.

All of my searches come up mentioning WCF and named pipes. I feel like it should be a simpler solution than this, like the self reference. Is WCF the way to go for this? Any other/better solutions?

ModuleHandler.cs:

using System;
using System.IO;
using System.Reflection;

namespace Collector
{
    class ModuleHandler
    {
        public ModuleHandler()
        {
            LoadStaticModules();
        }

        private void LoadStaticModules()
        {
            Assembly assembly = Assembly.Load("Module_WaitForIt");
            Type[] types = assembly.GetTypes();
            dynamic module = Activator.CreateInstance(types[0]);
            module.StartSleeping();
        }

        public void TestMethod()
        {
            Console.WriteLine("TestMethod()");
        }
    }
}

Module_WaitForIt:

using System.Threading;

namespace Module_WaitForIt
{
    public class WaitModule
    {
        public void StartSleeping()
        {
            System.Console.WriteLine("Sleeping");
            Thread t = new Thread(() => SleepyThread());
        }

        public void SleepyThread()
        {
            Thread.Sleep(10000);
        }
    }
}

In this example, I want Module_WaitForIt.SleepyThread() to call ModuleHandler.TestMethod() after it sleeps for 10 seconds.

sdouble
  • 999
  • 2
  • 9
  • 25
  • 3
    _"my dll can't communicate with it's parent process"_ - are you actually spawning a child surrogate process to load your DLLs? Or you you using child AppDomains? If the answer is no to both then you don't need communications - just invoke a method. – MickyD Mar 31 '16 at 13:29
  • If you are truly using two different processes on the _same machine_ check out _[Object Sharing between Applications?](http://stackoverflow.com/questions/28335037/object-sharing-between-applications)_. There are many forms of IPC for local machine, all more performant than WCF – MickyD Mar 31 '16 at 13:33
  • @MickyD WCF with named pipes binding is pretty fast. – nodots Mar 31 '16 at 13:42
  • @nodots yes, but straight-up named pipes without all the WCF and XML overhead is even faster. – MickyD Mar 31 '16 at 15:41
  • @MickyD Apologies, poor terminology. Basically, I have a directory with the dlls in it and am loading them via Assembly.Load() at runtime. I understand they aren't separate processes, I'll clear up my question and add some code. – sdouble Mar 31 '16 at 15:50
  • It appears you are 1) loading an assembly from a dll at runtime into your appdomain 2) instantiating a type defined within that assembly 3) call a method on it. There isn't any difference here between assemblies you've linked at compile time and those loaded at runtime. Simply call your long-running method passing in a callback func or action. The code you called can run in a different thread, then call back when it's done. You don't need any form of IPC for this, including wcf. –  Mar 31 '16 at 17:58

1 Answers1

0

There are a number of ways to do this that don't need WCF, e.g.

  • Your dynamically-loaded assembly can implement an interface or be derived from a base class that is defined in an assembly that is referenced by both your assembly and your parent assembly. This interface or base class could, for example, include events which you can raise to pass data to your parent assembly.

  • Your dynamically-loaded assembly can include methods that take parameters whose type is an interface defined in another assembly. When your parent calls your method, it passes you a concrete instance that implements that interface, and you can call it when appropriate.

Joe
  • 114,633
  • 27
  • 187
  • 321