[英]Autofac with generic services and repository
嘗試使用Autofac時,我面臨的體系結構設置問題。
遇到的錯誤消息如下:
在類型為“ 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
'。
存儲庫接口和類
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 {}
服務接口和類別
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{...}
控制器代碼
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();
}
}
我對服務和存儲庫的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();
我嘗試使用Register Generic方法,但仍然遇到相同的錯誤
builder.RegisterGeneric(typeof(GenericRepository<,>))
.As(typeof(IGenericRepository<,>))
.AsSelf()
.InstancePerDependency();
謝謝你的幫助。
最好的祝福。
錯誤消息指示未注冊IGenericService<EntCountry, Int32>
。
因為GenericService
是抽象的,所以第一個解決方案是擁有這樣一個類的實現。
public class FooService : GenericService<Foo, Int32>
{ }
然后Autofac將注冊FooService
作為IGenericService<Foo, Int32>
如果您不想實現,而只使用GenericService<T, TId>
,則必須刪除abstract
修飾符,並更改在Autofac中注冊類型的方式 。
不幸的是,在掃描程序集時,沒有簡單的方法來注冊開放的泛型類型。 Autofac Github中對此有一個未解決的問題: 支持在掃描程序集時注冊開放的通用類型
最簡單的解決方案是手動注冊此類型
builder.RegisterGeneric(typeof(GenericService<,>))
.AsImplementedInterfaces();
如果不可能,請查看Github問題,可以使用一些解決方案。
所提供的代碼也會有另一個問題。 IGenericService<T, TId>
具有類約束( where TId : class
),但例外是TId
是Int32
,對於.net運行時無效。 您應該刪除類約束或更改TId
的類型。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.