views:

231

answers:

3

Hi:

When .NET 2.0 came out I was very impressed by the Provider Factory pattern used for several of the services that were rolled out at that time...and started using it everywhere.

But then I ran into real troubles with it:

  • On CE, there was no config system, so it couldn't easily be ported to that environment (and therefore causing serious forks in code that could have otherwised worked on nicely on both frameworks with only a couple of modifications)
  • I never found a good answer to how to ensure that both the static Manager had wrapped all the methods of the Providers: the providerBase could implement an Interface, but interfaces (AFAIK) can't be used on static methods. So there was always a chance of divergence between the wrapped provider, and the static manager.
  • The amount of boiler plate code shot through the roof, and my productivity inversly dropped through the floor. By that I mean that instead of just calling instance.Method();

I was calling that, but through a static Manager.DoWork(), which was invoking its instance's DoWork(), which usually ended up being common code in the ProviderBase class, which checked the args, did some work, and finally called an abstract InternalDoWork(), which was implemented in the CustomProvider class...

In other words...a very tortuous way of invoking a method (3 to 4 methods, argument checking everywhere, unclarity of where to try/catch/log - in Manager or ProviderBase? -etc.

So, my question is: is there another pattern(s) that I can look at to give config file configuration capabilities, allowing dynamic changing -- well, atleast at restart -- of the service provider?

PS: I've heard much about IoC/DOI lately as being a possibly faster solution...although not used it in production. It looks interesting...But my first impression is that DOI seems to have the swapping of services, configurable in the config file, but not the setting of parameters from the config file?

Thanks!

A: 

Unity application block from Microsoft's Patterns and Practices group is pretty good. Though probably not the only or best one out there. Also the MEF framework is getting a good amount of talking about in Microsoft land as they are using/integrating it into Visual Studio 2010.

David McEwing
A: 

I think you'll want to look into Dependency Injection libraries like @David's Unity suggestion. I prefer Autofac. But there are others http://en.wikipedia.org/wiki/Dependency%5Finjection.

kenny
+1  A: 

If you want to explore dependency injection, I'd recommend the Ninject or StructureMap libraries. There are quite a few StackOverflow questions about .NET IoC containers though, so just search and you'll find a lot more information.

As for your actual question, the trend seems to be toward a Composition-based model, rather than a Subtyping one that the Provider model uses. This seems to map more closely to newer stuff coming out of Redmond, such as ASP.NET MVC.

Focusing on Composition means a design outlining "has a" relationships between parts, rather than "is a" relationships. They tend to focus on defining fewer contract details and letting specific implementations deal with how to fulfill the contract, instead of the forced construction route (using abstract methods) which is common in a Subtyping-based design and often over-engineers a solution toward a specific implementation. Both approaches have drawbacks (for instance, versioning is often cited as a challenge with a Composition based design using Interfaces) so it can depend on what you're doing.

In general, I think dependency injection is better for application code as composing your application often makes it less tightly coupled than defining a strict inheritance model and typically makes the code easier to unit test. Furthermore, a lot of the issues typically cited with composition are less important for application code than they are for frameworks (again, versioning). The truth is probably somewhere in the middle, as seen in MVC, where the dependencies between components use simple interfaces (Composition) but base classes implementing common functionality are also available to inherit and override only the necessary bits.

That's why IoC containers tend to help here because they provide loosely coupled means for a system to ask for a component without having to know anything about the implementation. For instance, DependencyResolver.GetInstanceOf<IUserRepository>().

krohrbaugh