Is this a good implementation of the factory method?

I am working on a module that requires a strictly decoupled interface. In particular, after creating an instance of the root object (data source), the user should interact only with the object model through interfaces. I have actual factory objects (I call them suppliers) to supply instances that implement these interfaces, but this left a clumsy clue in getting providers. For this, I provided a couple of methods for the data source:

public class MyDataSource { private Dictionary<Type, Type> providerInterfaceMapping = new Dictionary<Type, Type>() { { typeof(IFooProvider), typeof(FooProvider) }, { typeof(IBarProvider), typeof(BarProvider) }, // And so forth }; public TProviderInterface GetProvider<TProviderInterface>() { try { Type impl = providerInterfaceMapping[typeof(TProviderInterface)]; var inst = Activator.CreateInstance(impl); return (TProviderInterface)inst; } catch(KeyNotFoundException ex) { throw new NotSupportedException("The requested interface could not be provided.", ex); } } } 

I simplified some details on the fly to simplify (for example, this piece of code does not include the parameters passed to the implementation instance that I created). Is this a good general approach for implementing a factory method in C #?

+4
source share
5 answers

You should rather take a step back and ask if using the factory method is a good idea at all? In my opinion, this is not so.

There are several problems with factory methods, and your example illustrates several:

  • You need to have a solid reference to the implementation (FooProvider in addition to IFooProvider), which is exactly the situation that you are trying to avoid in the first place. Even if the rest of your code only consumes IFooProvider, your library is still closely related to FooProvider. Some other developers may come and start using FooProvider directly if he / she does not know your factory method.
  • You only support implementations that have default constructors since you are using Activator.CreateInstance. This will prevent the use of nested dependencies.

Instead of trying to manually manage dependencies, I would recommend that you take a look at Injection Dependency (DI). Whenever your code needs an IFooProvider, put it in a constructor injector.

+4
source

Do not invent your own implementation of dependency injection , use an existing library such as Spring.NET or the Microsoft Unity block .

Injection dependency is a common programming problem that you do not need to solve yourself. There are some good lightweight libraries (I mentioned a couple above) that do the job well. They support both declarative and imperative models for defining dependencies and are pretty good at what they do.

+3
source

Technically, this is normal, but in most cases, when I see a factory, it usually returns the same interface like, for example, something like IProvider , and not IFooProvider or IBarProvider , which makes no sense to me, If you have FooProvider and BarProvider, then What are the different interfaces for? I would use one IProvider interface and have FooProvider and BarProvider implement this.

+1
source

Regardless of the correctness or incorrectness of using the factory method (since this is not what you asked for!), Your implementation looks good to me.

Something that might work for you better than hardcoding for type matching is to put this information in a configuration file and load it into your application.

0
source

Why use this template all the time and abstract some of this type of logic in a reusable assembly. It uses reflection, generics, and attributes to define and bind specific types at runtime. http://www.codeproject.com/KB/architecture/RuntimeTypeLoader.aspx

This helps to alleviate Mark’s concern, because the implementation types are not hardcoded, and in the future, the implementation types are determined by the installation and not by reference to the project assembly.

0
source

All Articles