簡體   English   中英

Autofac覆蓋泛型類型的最后注冊

[英]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的最后一行( MainLog )在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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM