IoC Windows Service Architecture

I am traditionally an SQL guy. I have a bunch of C# experience under my belt, but these have all tended to be tooling or customisation projects.

I am now tasked with writing a application that does the following...

  • Runs as a windows service
  • Watches for files, and when they arrive, loads them to a DB
  • Monitor the DB for newly loaded files
  • Perform some complex parsing on those files (involves aggregating db records)
  • Additional interfaces are required (web site for query parsed data etc)
  • Multiple file types must be supported, multiple parsers must be supported.
  • So, this is my first foray into IoC and I am trying my best to do things corretly. I am using Autofac and am quite comfortable with the concepts. My issue is in understanding the composition root, when it is ok to pass a container, what do I replace my traditional notion of a 'factory' with. My app is structured with an L2S model and a generic repository interface over that. I use an Autofac module to register the concrete types. I have a logger and use a module to register the concrete types also. In my test console app (which will be replaced by a windows service host), I create a container and register the logger and dal modules etc. I can then resolve my file watching classes using constructor injection to inject the logger, and repository. I also inject a queue object (in my case a memory backed queue, but could be a db queue) onto which new files are enqueued (producer). At the other end of the queue, I need a consumer. So, depending on the type of file being dequeued, I need to use a different loader class. I would of historically use a factory pattern to return the appropriate concrete class. Since the loader class needs to have a logger and appropriate repository injected into it, I cannot see how to create an instance of the appropriate loader class to handle the item coming off the queue without giving my factory class a reference to the IoC container. I know I can inject various item handlers into my consumer class, but say I had 50 file types, or 100, that is impractical.

    After I understand how to do this, I need to do something similar to watch for new parsing jobs (entries in a db table) and process those, but I am assuming it'll follow a similar pattern to the above.

    Any advice folks? I am this far (small distance) away from binning my C# and going to SSIS for the file loading, then hacking some nasty parser code in SSIS. Please help a C# learner.


    I have realised that I can just new up a bunch of loader classes and put them in a dictionary and pass that into the constructor. That allows me to ask for a loader by name.


    It sounds like you're trying to container construct every entity in your application - use DI sparingly and only where you need substitutable behaviour, there's nothing wrong with plain old "new" where appropriate.

    Another suggestion could be to mark your custom file loaders with an interface, say IFileLoader, run through all loaded assemblies and (using reflection) detect the implemented loaders. Then, assemble all the loaders in a chain of responsibility so that if one loader can't process the file type in question, it passes on the responsibility to the next. This way, it will be easy to add new loaders and the file watching part is clearly separated from the loading part. The COR pattern is not a must, the functionality can of course be provided with a simple loop.


    Here's my take on how you as a newbie should start.

    Start writing your classes. All dependencies on other classes are taken in the constructor.

    Since you never new up a class to get an instance at any other point than when you are constructing your objects, it will make your program look similar to this:

    static void Main(..) {
      var s1 = ...;
      var s2 = ...;
      var sn = ... SN(s1, s2, ..);
      sn.Wait();
    }
    

    Now you can replace all ... with registrations in your container. You don't use factory classes at all; an IoC container IS your factory. And then you replace the very root initialisation:

    var sn = container.Resolve<SN>();
    

    Now you are using IoC. Don't use a dictionary.

    链接地址: http://www.djcxy.com/p/11250.html

    上一篇: 32和33杀号发生了什么?

    下一篇: IoC Windows服务体系结构