Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I get a portion of my C# app to load dynamically without app restart?

My C# application server.exe is critical to my business operations and ideally needs to run without interruption 24/7. The code is rock solid but one thing that's out of my control is the poor quality of inbound data feeds that are generated by third parties. I'll occasionally receive data feeds that contain anomalies in which case I must:

  • update the feed processing code within server.exe to accommodate the anomaly
  • recompile
  • restart server.exe using the new code and allow the syntactically flawed feed to be processed

The whole process usually takes less than a couple of minutes but the restart of server.exe causes the reset of certain non-critical state information and worse, causes a disruption of external processes that depend upon server.exe.

My goal: Isolate the feed processing code into a separate DLL whose contents can be updated without restarting server.exe. How do I do this?

Allow me to explain what I've done so far prior to writing this forum post:

The feed processor interface has been moved to a new assembly called common.dll. The interface looks something like this:

public interface IFeedProcessor{
    bool ProcessFeed(String filePath);  //returns false on failure, true on success
}

Server.exe now references common.dll.

The feed processors themselves have been moved to a new assembly called feedProcessors.dll. The implementations look something like this:

internal class FeedProcessor1:IFeedProcessor{
    public FeedProcessor1(){}
    bool ProcessFeed(String filePath){/*implementation*/return true;}
}

internal class FeedProcessor2:IFeedProcessor{
    public FeedProcessor2(){}
    public bool ProcessFeed(String filePath){/*implementation*/return true;}
}

[... and so on...]

feedProcessors.dll also contains a class named FeedProcessorUtils that's used to create a specific feed processor based on some configuration inputs. It looks something like this:

public class FeedProcessorUtils{
    public static void CreateFeedProcessor(int feedType /*and other configuration params*/){
        switch(feedType){
            case 1:return new FeedProcessor1();
            case 2:return new FeedProcessor2();
            default: throw new ApplicationException("Unhandled feedType: "+feedType);
        }
    }
}

Everything works just as before but of course it doesn't solve my dynamic loading problem; If I updated feedProcessors.dll with new code and copy it to the production server, I'm unable to do so because the file is in use. No surprise there. So what's the solution?

Ideally I want to be able to copy an updated feedProcessors.dll to the production server without a file-in-use error and without restarting server.exe. Then, the next time server.exe makes a call to FeedProcessorUtils.CreateFeedProcessor(), it'll be executing from my revised DLL instead of the old one.

Where do I start?

like image 458
Chad Decker Avatar asked Apr 12 '14 20:04

Chad Decker


2 Answers

You want to use shadow copy assemblies for the dynamically loaded DLL http://msdn.microsoft.com/en-us/library/ms404279(v=vs.110).aspx

like image 64
Dave Bush Avatar answered Oct 29 '22 16:10

Dave Bush


Sounds like a classic place to use MEF: http://msdn.microsoft.com/en-us/library/dd460648(v=vs.110).aspx

I suggest you look into it and ask questions as you proceed.

like image 43
Yuval Itzchakov Avatar answered Oct 29 '22 17:10

Yuval Itzchakov