[英]Autofac with generic services and repository
I'am facing an issue with the architecture set in place while trying to use Autofac. 尝试使用Autofac时,我面临的体系结构设置问题。
Error message encountered is the following: 遇到的错误消息如下:
None of the constructors found with 'Autofac.Core.Activators.Reflection.DefaultConstructorFinder' on type 'xx.xx.xxxxxxx.HomeController' can be invoked with the available services and parameters: Cannot resolve parameter 'xx.Service.Common.IGenericService
2[xx.Common.Models.EntCountry,System.Int32] countryService' of constructor 'Void .ctor(xx.Service.Common.IGenericService
2[xx.Common.Models.EntCountry,System.Int32])'.在类型为“ xx.xx.xxxxxxx.HomeController”上使用“ Autofac.Core.Activators.Reflection.DefaultConstructorFinder”找到的构造函数均无法使用可用的服务和参数进行调用:无法解析参数“ xx.Service.Common.IGenericService
2[xx.Common.Models.EntCountry,System.Int32] countryService' of constructor 'Void .ctor(xx.Service.Common.IGenericService
2 [xx.Common.Models.EntCountry,System.Int32])的2[xx.Common.Models.EntCountry,System.Int32] countryService' of constructor 'Void .ctor(xx.Service.Common.IGenericService
'。
Repository Interface and Class 存储库接口和类
public interface IGenericRepository<T,TId>
where T: class , IEntity<TId>
{...}
public abstract class GenericRepository<T, TId> : IGenericRepository<T, TId>
where T : class, IEntity<TId>
where TId : class {}
Service Interface and Class 服务接口和类别
public interface IGenericService<T,TId> where T : class , IEntity<TId>
{...}
public abstract class GenericService<T, TId> : IGenericService<T, TId>
where T : class, IEntity<TId>
where TId : class{...}
Controller Code 控制器代码
public class HomeController : Controller
{
private readonly IGenericService<EntCountry, int> _countryService;
public HomeController(IGenericService<EntCountry, int> countryService)
{
_countryService = countryService;
}
// GET: Home
public ActionResult Index()
{
var countries = _countryService.GetAll();
return View();
}
}
My Autofac configuration for services and repository is the following: 我对服务和存储库的Autofac配置如下:
builder.RegisterAssemblyTypes(Assembly.Load("XX.Data"))
.Where(t => t.Name.EndsWith("Repository"))
.AsImplementedInterfaces()
.AsSelf()
.PropertiesAutowired(PropertyWiringOptions.AllowCircularDependencies)
.InstancePerLifetimeScope();
builder.RegisterAssemblyTypes(Assembly.Load("XX.Service"))
.Where(t => t.Name.EndsWith("Service"))
.AsImplementedInterfaces()
.AsSelf()
.PropertiesAutowired(PropertyWiringOptions.AllowCircularDependencies)
.InstancePerLifetimeScope();
I tried to use the Register Generic method, but I still got the same error 我尝试使用Register Generic方法,但仍然遇到相同的错误
builder.RegisterGeneric(typeof(GenericRepository<,>))
.As(typeof(IGenericRepository<,>))
.AsSelf()
.InstancePerDependency();
Thanks for your help. 谢谢你的帮助。
best regards. 最好的祝福。
The error message indicates that IGenericService<EntCountry, Int32>
is not registered. 错误消息指示未注册
IGenericService<EntCountry, Int32>
。
Because GenericService
is abstract the first solution would be to have an implementation of such a class 因为
GenericService
是抽象的,所以第一个解决方案是拥有这样一个类的实现。
public class FooService : GenericService<Foo, Int32>
{ }
Then Autofac will register FooService
as IGenericService<Foo, Int32>
然后Autofac将注册
FooService
作为IGenericService<Foo, Int32>
If you don't want to have an implementation but only use GenericService<T, TId>
you will have to remove the abstract
modifier and change how you register your type in Autofac . 如果您不想实现,而只使用
GenericService<T, TId>
,则必须删除abstract
修饰符,并更改在Autofac中注册类型的方式 。
Unfortunately there is no easy way to register an open generic type when scanning assemblies. 不幸的是,在扫描程序集时,没有简单的方法来注册开放的泛型类型。 There is an active open issue about this in Autofac Github : Support registering open generic types when scanning assemblies
Autofac Github中对此有一个未解决的问题: 支持在扫描程序集时注册开放的通用类型
The easiest solution is to register this type manually 最简单的解决方案是手动注册此类型
builder.RegisterGeneric(typeof(GenericService<,>))
.AsImplementedInterfaces();
If it is not possible have a look at the Github issue there is some solution you could play with. 如果不可能,请查看Github问题,可以使用一些解决方案。
There will also be another issue with the code provided. 所提供的代码也会有另一个问题。 The
IGenericService<T, TId>
has a class constraint ( where TId : class
) but in the exception TId
is a Int32
wich is not valid for the .net runtime. IGenericService<T, TId>
具有类约束( where TId : class
),但例外是TId
是Int32
,对于.net运行时无效。 You should remove the class constraint or change the type of TId
. 您应该删除类约束或更改
TId
的类型。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.