Question

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?

Was it helpful?

Solution

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

OTHER TIPS

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.

In addition to the shadow copy option, you should create an AppDomain and check when your dll is changed to restart the domain and reload the dll, you can check this with a FileSystemWatcher.

Take care of not directly referencing your classes between AppDomains, or your old assembly will never be unloaded.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top