Reputation: 2366
First of, sorry if my use of terms are invalid, trying to get it right but not sure if it is, it's a little confusing for me right now.
I'm using Windsor and having trouble figuring out when and how (I think) to use interface-based factories instantiating and not always the normal ctor(IObj obj)
.
Let me give an example. I have this constructor
private ICache _cache;
private ICache _cache2;
public HomeController(ICacheFactory cacheFactory, ICache cache)
{
this._cache = cacheFactory.Create<ICacheFactory>();
this._cache2 = cache;
}
The way I have setup my code, _cache
and _cache2
return the exakt same object. Why should I ever use the ICacheFactory
way of instansiating a class?
This is how I've configured it
public interface ICacheFactory
{
ICache Create<T>();
}
public interface ICache
{
bool Get<T>(string key, out T exists);
}
public bool Get<T>(string key, out T result)
{
// my code
}
public void Install(IWindsorContainer container, IConfigurationStore store)
{
container.Register(Classes.FromThisAssembly().BasedOn<IController>().LifestyleTransient());
container.AddFacility<TypedFactoryFacility>();
container.Register(Component.For<ICacheFactory>().AsFactory());
container.Register(Component.For<ICache>().ImplementedBy<CacheFactory>().LifestyleTransient());
}
I'm thinking CacheFactory as when I do
public class CacheFactory : ICache
{
private static ICache cacheObject;
public static ICache Current
{
get
{
if (cacheObject == null)
cacheObject = new CacheFactory();
return cacheObject;
}
}
public bool Get<T>(string key, out T result)
{
// my code
}
}
So am I complety way of in my way of thinking what the interface-based factories
do and if not why should I ever use the ICacheFactory
way of instansiating a class?
(I should be clear that I've read the Windsor documentation but not getting it 100%.)
Thanks for your time and I hope it's not to fuzzy.
Upvotes: 1
Views: 84
Reputation: 172646
When applying dependency injection correctly, you'll find that this will dramatically reduce the amount of factories you need to use. Factories are still useful and sometimes needed, but their use is limited to the times that you either:
In most other cases, factories should not be used. Especially in the case that you are showing, where the factory is called inside the constructor. This is useless, because:
HomeController
now has a dependency on an extra abstraction ICacheFactory
, while it could fulfill its needs with just the dependency on ICache
alone. This also complicates testing. Why doe HomeController
need to know about this factory at all?Furthermore, you are stating that "_cache and _cache2 return the exact same object", so there's no need to inject two caches here. So your constructor should be like:
private ICache _cache;
public HomeController(ICache cache)
{
this._cache = cache;
}
If your factory contains complex behavior to do the selection, you can still use it inside your Composition Root, but there might not be a reason for the application code to take a dependency on it.
Upvotes: 3