[英]Autofac - Register generic constraint
我正在嘗試向Autofac注冊通用組件。 我遇到的問題與以下鏈接中的問題類似(錯誤消息相同)。 使用通用存儲庫將autofac與webapi綁定
我正在使用洋蔥架構( http://jeffreypalermo.com/blog/the-onion-architecture-part-1/ )。 DbContext位於單獨的層中,而業務層是將獲取數據並執行與業務規則相關的各種操作的層。 上層只會知道接口IBaseDbManager。 我有一個垂直層,負責解決依賴關系。
下面的代碼和Autofac配置示例如下:
商務課程:
public class BaseDbManager<TContext> : IBaseDbManager where TContext : DbContext, IBaseContext
{
private readonly TContext _context;
public BaseDbManager(TContext context)
{
_context = context;
}
public Partner GetPersonInfo(Expression<Func<Person,bool>> predicate)
{
var person = _context.Persons.Where(predicate).FirstOrDefault();
return person;
}
}
業務接口:
public interface IBaseDbManager
{
Partner GetPersonInfo(Expression<Func<Person, bool>> predicate);
}
數據庫上下文:
[Database]
public class BaseContext : DbContext, IBaseContext
{
public BaseContext()
: base((string) ConnectionHelper.BaseConnectionString())
{
Database.SetInitializer<BaseContext>(null);
}
public virtual DbSet<Person> Persons { get; set; }
}
上下文界面:
public interface IBaseContext
{
DbSet<Partner> Partners { get; set; }
}
AUTOFAC模塊:
protected override void Load(ContainerBuilder builder)
{
builder.RegisterType<BaseContext>().As<IBaseContext>().InstancePerLifetimeScope();
builder.RegisterType(typeof(BaseDbManager<>)).As<IBaseDbManager>().InstancePerLifetimeScope();
}
問題在於,如果沒有無參數構造函數,Autofac將不知道如何解析IBaseDbManager。 我需要由Autofac解決TContext。 您如何配置Autofac來解決這些情況? 我嘗試注冊為泛型並且基於構造函數,但它也不起作用。 如果我將new()添加到約束中並在無參數構造函數中創建實例,則它可以工作...我不想以這種方式解決它。
我想念什么?
問題在於,如果沒有無參數構造函數,Autofac將不知道如何解析IBaseDbManager。
那不是問題。 這里的構造函數不是問題,Autofac不會對您的構造函數施加任何約束。
這里的問題是,在給定開放通用BaseDbManager<T>
,Autofac不知道要創建哪個封閉通用版本,因為給定的IBaseDbManager
抽象是非通用的。 它無法為您推斷通用類型。
有幾種解決方案,但是由於應用程序中不同上下文類型的數量很可能非常有限(通常只有1個),因此在注冊中指定此上下文類型最有意義。 例如:
builder.RegisterType(typeof(BaseDbManager<BaseContext>)).As<IBaseDbManager>()
.InstancePerLifetimeScope();
如果BaseContext
是您唯一的上下文類型,則使BaseDbManager<T>
為非泛型甚至更有意義,因為只有當您實際計划更改類型參數T
,使它成為泛型才有意義。
我有兩個與TContext約束匹配的對象(BaseContext和FakeBaseContext)。 BaseContext查詢數據庫,FakeBaseContext使用專門為單元測試創建的虛假數據。
這似乎不是擁有另一個上下文類的正當理由; 上下文是一組實體的定義; 在測試期間,您擁有相同的實體集。
在查看Autofac文檔的幾節內容后,我發現了與Steven的方法結合使用的注冊件,該注冊件使Autofact能夠正確解決依賴關系(請參見下面的鏈接):
http://docs.autofac.org/en/latest/register/parameters.html?highlight=WithParameter
我最終編碼的模塊注冊如下:
protected override void Load(ContainerBuilder builder)
{
builder.RegisterType<BaseContext>()
.As<IBaseContext>()
.InstancePerLifetimeScope();
builder.RegisterType<BaseDbManager<BaseContext>>().As<IBaseDbManager>()
.WithParameter(new TypedParameter(typeof(BaseContext), new BaseContext()))
.InstancePerLifetimeScope();
}
額外的反饋將不勝感激。 我將繼續重構我的代碼,因為我認為它可以改善。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.