Dependency inversion. Object creation
According to SOLID principles a class cannot depend on other classes, dependencies have to be injected. It's simple:
class Foo
{
public Foo(IBar bar)
{
this.bar = bar;
}
private IBar bar;
}
interface IBar
{
}
class Bar: IBar
{
}
But what if I want my Foo class to be able to create Bar's, not knowing the exact implementation behind IBar? I can think of 4 solutions here, but all of them seem to have drawbacks:
class Foo
{
public void DoSmth(IBarCreator barCreator)
{
var newBar = barCreator.CreateBar();
}
}
interface IBarCreator
{
IBar CreateBar();
}
class BarCreator : IBarCreator
{
public IBar CreateBar()
{
return new Bar();
}
}
Last case seems natural, but BarCreator class has too litle code. So how do you think, which is best?
I like to "inject" a Func<IBar>
in this case. Like so:
class Foo
{
public Foo(Func<IBar> barCreator)
{
this.bar = barCreator();
}
private IBar bar;
}
interface IBar
{
}
This is what factories were made for.
If you feel your factory has too little code, ask yourself what benefit it's giving you over just creating the instance inline. If the benefits outweigh the costs of the added code, then don't worry about it.
I'd personally avoid service location, or if you really must use it I'd hide it behind a factory anyway. Service location tends to be easily abused, and can lead to your container finding its way into code it shouldn't have anything to do with.
For convenience, some containers allow you to specify a factory to be used by the container when it creates an instance of a component. In this case, your class could depend on IBar
directly but your container would call IBarCreator
when it needs a new instance. Castle Windsor has the methods UseFactory
and UseFactoryMethod
in their API, for example.
it all depends on your exact scenario and your needs.
I think the most used approach is, as you've mentioned, a factory.
If you're using an IoC framework (such as Ninject, or Sprint.Net, Castle Windsor etc. see here), a service locator is also a viable solution.
上一篇: 组织数据库工作的最佳方式
下一篇: 依赖倒置。 对象创建