[英]Autofac overrides last registration for generic type
我試圖向Autofac注冊通用類型,但最后一個值最終將覆蓋先前的值。 普通項目有實體服務接口,
public interface IEntityService<TEntity> where TEntity : class
{
TEntity GetByID(object id);
}
實施類,項目A
public class EntityService<TEntity> : Common.IEntityService<TEntity> where TEntity : class
{
protected IContext _iContext;
protected DbSet<TEntity> _iDbSet;
public EntityService(IContext context)
{
_iContext = context;
_iDbSet = IContext.Set<TEntity>();
}
public virtual TEntity GetByID(object id)
{
return IDbSet.Find(id);
}
}
實施類項目B
public class EntityService<TEntity> : Common.IEntityService<TEntity> where TEntity : class
{
protected ILogDbContext _iLogDbContext;
protected DbSet<TEntity> _iDbSet;
public EntityService(ILogDbContext context)
{
_iLogDbContext = context;
_iDbSet = IContext.Set<TEntity>();
}
public virtual TEntity GetByID(object id)
{
return _iDbSet.Find(id);
}
}
在web.api中注冊
var builder = new ContainerBuilder();
builder.RegisterModule(new EFModule());
var container = builder.Build();
config.DependencyResolver = new AutofacWebApiDependencyResolver(container);
EFModule類
public class EFModule : Module
{
protected override void Load(ContainerBuilder builder)
{
builder.RegisterGeneric(typeof(Service.EntityService<>))
.As(typeof(Common.IEntityService<>))
.Named(Common.ConfigType.ProjectType.Main,typeof(Common.IEntityService<>))
.InstancePerDependency();
builder.RegisterGeneric(typeof(LogProject.Service.EntityService<>))
.As(typeof(Common.IEntityService<>))
.Named(Common.ConfigType.ProjectType.Log, typeof(Common.IEntityService<>))
.InstancePerDependency();
}
}
發生的是,對於最后的任何配置,一切都可以正常工作。 說,我把
builder.RegisterGeneric(typeof(LogProject.Service.EntityService<>))
在web.config中,項目類型為LogProject
。 然后工作正常,但是如果我將MainProject
放在配置文件中。 反過來,無論module
的最后一行( Main
或Log
)在web.config
,如果web.config
的行與它覆蓋的內容不相同,則會發生異常。 基本上,泛型不是基於但基於解析,而是被最后一個值覆蓋。
您正在注冊2個typeof(Common.IEntityService<>)
實例。 最后注冊的實例獲勝是正常和預期的行為。
根據文檔 :
如果多個組件公開同一服務,則Autofac將使用最后注冊的組件作為該服務的默認提供程序
如果希望Autofac能夠區分兩者,則有兩種選擇:
public interface ILogEntityService<TEntity> : IEntityService<TEntity> where TEntity : class
{
}
將以上接口用於Log項目的構造函數參數,並按如下所示進行注冊:
builder.RegisterGeneric(typeof(Service.EntityService<>))
.As(typeof(Common.IEntityService<>))
.Named(Common.ConfigType.ProjectType.Main,typeof(Common.IEntityService<>))
.InstancePerDependency();
builder.RegisterGeneric(typeof(LogProject.Service.EntityService<>))
.As(typeof(ILogEntityService<>))
.Named(Common.ConfigType.ProjectType.Log, typeof(Common.IEntityService<>))
.InstancePerDependency();
builder.RegisterGeneric(typeof(Service.EntityService<>))
.AsSelf()
.Named(Common.ConfigType.ProjectType.Main,typeof(Common.IEntityService<>))
.InstancePerDependency();
builder.RegisterGeneric(typeof(LogProject.Service.EntityService<>))
.AsSelf()
.Named(Common.ConfigType.ProjectType.Log, typeof(Common.IEntityService<>))
.InstancePerDependency();
然后在服務構造函數中使用具體類型
public SomeService(ConcreteEntityService<SomeClass> foo)
當然,在能夠交換/模擬實現方面,使用第一個選項更好。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.