简体   繁体   English

接口依赖关系层次结构

[英]Interface dependency hierarchy

I currently have a main class which might call another class which might call 2 or 3 others. 我目前有一个主班,可能会叫另一个班,可能会叫另外2个或3个。 The main class might create a Windows form as well. 主类也可以创建Windows窗体。

So at the moment we might have: 因此,目前我们可能有:

public class MainClass
{
  ...
  AnotherClass = new AnotherClass();
  fmMain myForm = new fmMain();
}

public class AnotherClass
{
  ...
  DatabaseClass dbClass = new DatabaseClass();
  FileClass fClass = new FileClass();
}

As I see it, after refactoring and putting in constructor interface dependencies I can use an IOC container. 如我所见,在重构并放入构造函数接口依赖项之后,我可以使用IOC容器。

The problem is my entry point is the main class so all I can see to do is have all the dependencies in the main class constructor and then pass these down into the other classes and forms. 问题是我的入口点是主类,因此我能看到的是在主类构造函数中具有所有依赖项,然后将其传递给其他类和形式。

The issue is this could get very messy and the main class might have 10 dependencies most of which used in other classes. 问题是这可能会变得非常混乱,并且主类可能具有10个依赖关系,其中大多数依赖关系都在其他类中使用。 Is there an alternative? 还有其他选择吗?

Let the IoC container to do this. 让IoC容器执行此操作。

Register AnotherClass as a dependency and then resolve it directly referring to container instance. AnotherClass注册为依赖项,然后直接引用容器实例来解决它。

Dependencies should be defined locally to where they are required ie the dependencies should be defined on the constructors of the types, then use an IoC container to resolve all types. 应该在需要的地方本地定义依赖关系,即应该在类型的构造函数上定义依赖关系,然后使用IoC容器解析所有类型。 In this way the IoC takes care of "passing these down into the other classes and forms". 这样,IoC就负责“将这些信息传递给其他类和形式”。 When using an IoC container avoid using "new" whenever possible, and instead use the container to create instances. 使用IoC容器时,应尽可能避免使用“ new”,而应使用容器创建实例。 It will handle creation and injection of dependencies for you. 它将为您处理依赖关系的创建和注入。

For example (using Ninject), the following demonstrates a Form which defines its own dependencies. 例如(使用Ninject),下面的示例演示了定义其自身依赖关系的Form The container will supply and inject all dependencies recursively when used to resolve an instance of the ProductForm . 当用于解析ProductForm实例时,容器将递归提供和注入所有依赖项。

Dependencies do not need to be injected into the entry-point class, but are specified as bindings in a module and then injected by the container when types such as Forms are resolved. 依赖关系不需要注入到入口点类中,而是在模块中被指定为绑定,然后在解析诸如Forms类的类型时由容器注入。

public class Program
{
    public Program()
    {
        IKernel kernel = new StandardKernel(new MainModule());

        Form form = kernel.Get<ProductForm>();

        form.Show();
    }
}

public class MainModule : NinjectModule
{
    public override void Load()
    {
        Bind<ProductForm>().ToSelf();
        Bind<IProductService>().To<ProductService>();
        Bind<IProductDb>().To<IProductDb>();
    }
}

internal class ProductForm : Form
{
    private readonly IProductService _productService;

    public ProductForm(IProductService productService)
    {
        _productService = productService;
    }
}

internal interface IProductService {}

internal class ProductService : IProductService
{
    private readonly IProductDb _productDb;

    public ProductService(IProductDb productDb)
    {
        _productDb = productDb;
    }
}

internal interface IProductDb {}

internal class ProductDb : IProductDb {}

It sounds like your Main class is your Composition Root . 听起来您的主要课程是您的作文根 That's fine - it's not going to become messy if that's the only thing it does. 很好-如果那是唯一的事情,那不会变得混乱。 This should be its single responsibility. 这应该是它的单一责任。 In other words: your application entry point should be a Humble Object . 换句话说:您的应用程序入口点应该是Humble Object

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM