考虑到这些依赖关系不应该由客户端而是由DLL本身处理,同时仍符合SOLID和其他良好实践(可测试等),因此公开我的可分发DLL的API并处理其依赖关系的最佳方法是什么? ?
我能想到的唯一方法是通过使用带有静态工厂的Poor Man's Injection公开无参数构造函数,如下所示:
public class MyService
{
public MyService()
: this(DependencyFactory.CreateObjectA(), DependencyFactory.CreateObjectB())
{
}
internal MyService(IObjectA objectA, IObjectB objectB)
{
}
}
internal static class DependencyFactory
{
internal static IObjectA CreateObjectA()
{
return new ObjectA();
}
internal static IObjectB CreateObjectB()
{
return new ObjectB();
}
}
这是走的正确道路吗?
最佳答案
我建议您为组件保留一个公共构造函数,如下所示:
public class MyService
{
public MyService(IObjectA objectA, IObjectB objectB)
{
}
}
然后创建一个默认工厂,您的库的客户端可以使用它来提供便利,如下所示:
public static class MyConvenientFactory
{
public static MyService CreateDefaultMyService()
{
return new MyService(new ObjectA(), new ObjectB());
}
}
客户将像这样创建您的组件:
var service = MyConvenientFactory.CreateDefaultMyService();
或更高级的客户端将执行以下操作:
var service =
new MyService(
new CachingDecoratorForA(
new ObjectA()),
new LoggingDecoratorForB(
new PerformanceRecorderForB(
new ObjectB())));
其中
CachingDecoratorForA
,LoggingDecoratorForB
和PerformanceRecorderForB
是由您作为库提供者或客户端本身创建的装饰器。这允许客户端通过不同的组成来定制您的组件。这是应用SOLID原则的好处之一。有关对象组成和SOLID的一些讨论,请参见this article。
如果出于某种原因,您不希望这样的高级客户端通过合成来定制组件,则可以将构造函数的访问修饰符更改为
internal
,如下所示:public class MyService
{
internal MyService(IObjectA objectA, IObjectB objectB)
{
}
}