Autofac中注册开放泛型类型报错:Repository<T>无法分配给IRepository<T>
嘿,我之前在把StructureMap迁移到Autofac的时候也踩过类似的泛型注册坑,咱们来一步步搞定这个问题~
首先,你遇到的System.ArgumentException: 'The type 'Repository1[T]' is not assignable to service 'IRepository1'.'错误,本质是Autofac找不到Repository<>和IRepository<>之间的实现关系,大概率是这几个原因导致的:
1. 命名空间引用不匹配
你原来的StructureMap代码明确指定了Data.New命名空间下的类型,但Autofac的代码里可能省略了命名空间,导致引用了其他地方的同名类型。比如如果你的项目里还有另一个Repository<>或者IRepository<>,Autofac就会认错类型。
修正写法:把完整命名空间加上,确保注册的是正确的类型:
builder.RegisterType(typeof(Data.New.Repository<>)) .As(typeof(Data.New.IRepository<>));
如果已经在代码顶部加了using Data.New;,那简化写法也可以,但如果有同名类型冲突,一定要用完整命名空间。
2. 泛型类的实现关系有问题
要确认Data.New.Repository<T>确实正确实现了Data.New.IRepository<T>,注意泛型参数的匹配。比如你的类应该是这样的:
namespace Data.New { public class Repository<T> : IRepository<T> { // 这里要实现IRepository<T>的所有接口方法 } }
如果你的泛型类是Repository<TEntity>实现IRepository<T>(泛型参数名称不一致),虽然语法上合法,但Autofac的泛型匹配逻辑可能会出问题,尽量保持泛型参数名称一致,或者确保实现关系是严格的IRepository<T>。
3. 项目引用或程序集加载问题
如果Repository<>和IRepository<>在不同的项目里,要确保Autofac所在的项目已经正确引用了包含这两个类型的项目,并且没有程序集版本冲突。可以在调试时检查这两个类型的Assembly属性,确认是同一个程序集里的。
最终正确的注册示例
结合上面的要点,完整的Autofac注册代码应该是这样的(如果需要指定生命周期,比如实例每次请求创建,可以加上InstancePerDependency()):
var builder = new ContainerBuilder(); // 注册泛型仓储 builder.RegisterType(typeof(Data.New.Repository<>)) .As(typeof(Data.New.IRepository<>)) .InstancePerDependency(); // 根据你的业务需求选择生命周期 var container = builder.Build();
这样应该就能解决那个"类型不可分配"的错误啦~
内容的提问来源于stack exchange,提问作者Peuge

