Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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.

like image 688
trickbooter Avatar asked Oct 02 '12 22:10

trickbooter


People also ask

How do IoC containers work?

IoC Container It manages object creation and it's life-time, and also injects dependencies to the class. The IoC container creates an object of the specified class and also injects all the dependency objects through a constructor, a property or a method at run time and disposes it at the appropriate time.

What is IoC configuration?

Configuration is a container agnostic configuration of dependency injection. IoC. Configuration is a wrapper around popular IoC containers, with additional functionality (see below). Currently Ninject and Autofac are supported through the usage of Nuget extension packages IoC.

Which IoC container is best?

You can waste days evaluating IOC containers. The top ones are quite similar. There is not much in this, but the best ones are StructureMap and AutoFac. At SSW we use Autofac on most projects.

What is built in IoC container?

The IoC container that is also known as a DI Container is a framework for implementing automatic dependency injection very effectively. It manages the complete object creation and its lifetime, as well as it also injects the dependencies into the classes.


3 Answers

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.

like image 131
trickbooter Avatar answered Sep 29 '22 11:09

trickbooter


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.

like image 26
mhoff Avatar answered Sep 29 '22 11:09

mhoff


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.

like image 21
Henrik Avatar answered Sep 29 '22 11:09

Henrik