考虑到这些依赖关系不应该由客户端而是由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())));


其中CachingDecoratorForALoggingDecoratorForBPerformanceRecorderForB是由您作为库提供者或客户端本身创建的装饰器。

这允许客户端通过不同的组成来定制您的组件。这是应用SOLID原则的好处之一。有关对象组成和SOLID的一些讨论,请参见this article

如果出于某种原因,您不希望这样的高级客户端通过合成来定制组件,则可以将构造函数的访问修饰符更改为internal,如下所示:

public class MyService
{
    internal MyService(IObjectA objectA, IObjectB objectB)
    {
    }
}

10-07 15:51