在没有指定接口的情况下在Windsor中注册组件是否可以?

Sim*_*eep 16 dependency-injection castle-windsor ioc-container

在没有指定接口的情况下在Windsor中注册组件被认为是不好的形式吗?即

container.Register(Component.For<MyClass>().LifeStyle.Transient);
Run Code Online (Sandbox Code Playgroud)

而不是......

container.Register(Component.For<IMyClass>().ImplementedBy<MyClass>().LifeStyle.Transient);
Run Code Online (Sandbox Code Playgroud)

我理解编码到接口而不是具体实现的好处,但是我们发现我们现在有很多接口,其中许多接口都是实际上只有一个实现的类.

Mar*_*ann 27

是的,可以在没有接口的情况下注册组件,但不是因为你给出的原因.

具体依赖

可能会发生组件依赖于具体类.例如,使用Entity Framework,消费者应该将ObjectContext注入其中.这是一个仍然需要注入的具体类,因为它应该在几个消费者之间共享.

因此,给定一个消费者的构造函数如下:

public FooRepository(FooObjectContext objectContext)
Run Code Online (Sandbox Code Playgroud)

你需要像这样配置容器:

container.Register(Component.For<FooObjectContext>());
Run Code Online (Sandbox Code Playgroud)

FooRepository 请求没有接口,所以注册接口没有任何意义(即使有一个接口可用),但您仍然必须注册具体类,因为Windsor 只能解析显式注册的类型.

只有一个实现的接口

那么只有一个实现的接口呢?消费者再一次决定要求.

想象一下,消费者有这个构造函数:

public Ploeh(IBar bar)
Run Code Online (Sandbox Code Playgroud)

Castle Windsor能够解决Ploeh的唯一方法就是注册IBar.即使Bar是IBar的唯一实现,这也行不通:

container.Register(Component.For<Bar>());
Run Code Online (Sandbox Code Playgroud)

这不起作用,因为IBar从未注册过.Castle Windsor并不关心Bar实施IBar,因为它不希望代表您变得聪明.你必须明确告诉它:

container.Register(Component.For<IBar>().ImplementedBy<Bar>());
Run Code Online (Sandbox Code Playgroud)

IBar 映射到Bar.

注册接口和具体类型

那么如果您希望能够解决具体类型和界面呢?

上一个示例的问题是它可以让你解决IBar,但不能解决Bar.

您可以使用Forward方法或For的多重超载来转发注册:

container.Register(Component.For<Bar, IBar>().ImplementedBy<Bar>());
Run Code Online (Sandbox Code Playgroud)

这使您可以解决这两个酒吧和伊巴尔.

  • 另一个很好的例子是MVC应用程序中的控制器 - 您不需要抽象它们. (2认同)