楼梯模式实施

时间:2015-03-25 15:08:25

标签: c# .net decoupling

我遇到了" Stairway" "自适应代码中的模式描述通过C#"书,我真的不明白这是如何实现的:

Stairway patternsource

所以我有客户装配:

using ServiceInterface;

namespace Client
{
    class Program
    {
        static void Main(string[] args)
        {
            // Have to create service implementation somehow
            // Where does ServiceFactory belong?
            ServiceFactory serviceFactory = new ServiceFactory();
            IService service = serviceFactory.CreateService();
            service.Do();
        }
    }
}

服务接口程序集:

namespace Service
{
    public interface IService
    {
        void Do();
    }
}

服务实施程序集:

using ServiceInterface;

namespace ServiceImplementation
{
    public class PrintService : IService
    {
        public void Do()
        {
            Console.WriteLine("Some work done");
        }
    }
}

问题是:如何在IService命名空间中获取Client对象?我应该在哪里放置实际的new PrintService()对象?这不能成为ServiceInterface的一部分,因为界面汇编并不依赖ServiceImplementation。但它也不能成为ClientServiceImplementation的一部分,因为Client应仅依赖于ServiceInterface

我遇到的唯一解决方案是在其上面安装Application程序集,其中包含对所有三个程序集的引用(ClientServiceInterfaceServiceImplementation)并注入{ {1}}进入IService。我错过了什么吗?

3 个答案:

答案 0 :(得分:19)

根据Mark Seemann关于依赖注入的优秀书籍,应用程序入口点应该是组合根。在这里,问题更多的是关于依赖性倒置,客户端和实现都应该依赖于抽象。

该图表没有显示,但希望本书的其他部分明确指出,入口点自然而且必然会引用所有来构建任何你的解析根源(控制器,服务等。)但这是唯一有这种知识的地方。

请记住,客户有时可以“拥有”他们所依赖的接口:接口ISecurityService可能存在于Controllers程序集中,IUserRepository可能会存在在ServiceImplementations程序集中,依此类推。当然,当> 1客户端需要访问界面时,这是不切实际的。

如果您遵循SOLID,您自然会发现依赖注入是必需的,但控制反转容器不是优先考虑的事情。我发现自己越来越多地使用Pure Dependency Injection(手动构建解析根)。

答案 1 :(得分:2)

在这种情况下,Client项目应包含对ServiceServiceImplementation的引用。这些引用仅用于创建将用作DI的IoC容器。在应用程序启动时,您需要在IoC容器中注册所有接口实现。

如果您要针对ServiceImplementation界面实施Service,并且您将基于Client interface对Service进行编码,那么就不会依赖ServiceImplementation

您还可以在“自适应代码通过C#”的示例中看到如何实现Stairway模式:

https://github.com/garymcleanhall/AdaptiveCode/tree/master/Sprints/sample-sprint2-markdown

答案 2 :(得分:1)

我会把它放在ServiceFactory中。你需要一些参数,例如传递给工厂构造函数或从配置等中检索,确定工厂创建的IService实现。