c# - Autofac:类型“...”不可分配给服务“...”。
问题描述
考虑以下类和接口:
interface IFactory<T>{}
class Factory<T> : IFactory<T>{ }
interface IEntity{}
class Entity : IEntity{ }
我希望 Autofac 解决IFactory<IEntity>
这样的Factory<Entity>
问题:
b.RegisterType<Factory<Entity>>().As<IFactory<IEntity>>();
但我得到以下异常(为清楚起见缩写):
The type 'Factory`1[Entity]' is not assignable to service 'IFactory`1[[IEntity]]'
为什么会这样?如何解决这个问题?还是我在尝试“错误”的东西?
我简要研究了RegisterGeneric
,但我认为它不适用于这里;另外,因为上面只是一个例子。在其他情况下,我可能想为IFactory<IEntity>
.
解决方案
这不是 Autofac 问题 - 这是一般差异的问题。您会在一个简单的 C# 程序中看到完全相同的内容:
public class Program
{
public static void Main()
{
IFactory<IEntity> factory = new Factory<Entity>();
}
}
大多数通用接口是不变的——类型参数必须完全匹配。有些是协变的,例如IEnumerable<T>
,允许您编写:
IEnumerable<object> objects = new List<string>();
有些是逆变的,例如IComparer<T>
,允许您编写:
IComparer<string> = Comparer<object>.Default;
协变接口只允许它们的类型参数从实现中“出来”(例如通过返回类型)。逆变接口只允许它们的类型参数“进入”实现(例如通过常规参数)。当您拥有本身接受值等的委托参数时,它会变得微妙,但我们现在将忽略它......
听起来你IFactory<T>
应该是协变的 - 所以你只需像这样更改声明:
interface IFactory<out T>{}
那时,代码可以编译,我希望Autofac 也能处理它。不过,这确实要求您的界面永远不要T
用作输入。(我们无法确定,因为您没有显示任何界面成员。)
有关通用方差的更多详细信息,请参阅MS 文档。
推荐阅读
- python - 如何解决导入错误:pycurl lib. 在基于 Debian 的系统上安装它: $ 'sudo apt-get install python3-pycurl'
- javascript - onclick 功能改变视频
- javascript - 多租户 React 应用程序 - 租户特定配置
- npm - 如何使用 npm 跨平台运行 shell 脚本
- asynchronous - 微服务的 AsyncLocalStorage 不起作用
- jquery - Googleapis库jquery版本
- python - 特定值之间的随机整数,不包括 0
- signalr - 服务器端 Blazor 的成本有多高?
- flutter - W/FlutterActivityAndFragmentDelegate(27114):向 Flutter 提供了启动画面,但不推荐使用
- python - 在 python 中使用拟合数据有效求解超定非线性方程组