【问题标题】:How to resolve instance of base interface with Simple Injector如何使用 Simple Injector 解析基本接口的实例
【发布时间】:2016-04-28 12:10:06
【问题描述】:

我有一个继承自另一个接口的接口

public interface ISpecificHandler : IHandler

使用 Simple Injector 我注册了我的类型和实现

container.RegisterSingleton<ISpecificHandler, SpecificHandlerImpl>();

但是我怎样才能解决IHandler 而不是ISpecificHandler

//Expect SpecificHandlerImpl as handler
IHandler handler = ServiceLocator.GetInstance<IHandler>(); //error

这会抛出一个InvalidOperationException,表明 IHandler 类型未注册

【问题讨论】:

  • 为什么要这样做?你有多少个IHandler 实现?
  • 这只是一个示例场景。无论如何,我可以有多个实现。如果我可以将 SpecificHandlerImpl 转换为 IHandler 为什么不通过 IOC 容器解决它们!?
  • “为什么不通过 IOC 容器也解决它们!?”。因为这很容易导致您的代码和设计出现歧义。在没有更具体的情况下,没有人可以真正建议您解决此问题的最佳方法。所以我建议发布完整的IHandlerISpecificHandler 定义,描述你有多少其他实现,并展示一些你期望如何使用这个IHandler 的例子。

标签: c# ioc-container simple-injector


【解决方案1】:

有多种解决方案,但这实际上取决于您的应用程序真正需要什么。以下是一些建议。

您只需注册两次实现:

container.Register<IHandler, SpecificHandlerImpl>(Lifestyle.Scoped);
container.Register<ISpecificHandler, SpecificHandlerImpl>(Lifestyle.Scoped);

但也许您想解析多个处理程序,在这种情况下,您可能必须将它们注册为一个集合:

var reg1 = Lifestyle.Singleton.CreateRegistration<SpecificHandlerImpl>();
var reg2 = Lifestyle.Singleton.CreateRegistration<AnotherHandlerImpl>();

container.RegisterCollection<IHandler>(new[] { reg1, reg2 });

但是在使用非泛型 IHandler 接口时,您可能会遇到麻烦,因为您通常会有一个应该在特定场景中执行的特定实现(换句话说,您可能违反了 Liskov Substitution Principle) .因此,您通常最好使用通用的IHandler&lt;T&gt; 抽象,其中T 是一个包含处理程序值的参数对象。在这种情况下,封闭的IHandler&lt;T&gt; 和实现之间总是存在一对一的映射。 This article 很好地解释了这种设计的优点。

但在不知道您要解决的问题的情况下,很难说出适合您的解决方案。

【讨论】:

  • 谢谢 Steven,现在我是 IOC 容器和 SimpleInjector 的新手。提供的代码只是了解 SimpleInjector 细节的试用项目的一部分。但现在我意识到这种行为不是特定于实现的,而是为了防止不确定性
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-06-07
  • 2014-03-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多