[英]Autofac register nested type?
可以說我有這四種類型(帶有構造函數)。
public class MyDbContext : IDataContextAsync
{
public class MyDataContext() { }
}
public class UnitOfWork : IUnitOfWorkAsync
{
public UnitOfWork(IDataContextAsync dataContext)
{
_dataContext = dataContext;
}
}
public class Repository<TEntity> : IRepositoryAsync<TEntity>
{
public Repository(IDataContextAsync context, IUnitOfWorkAsync unitOfWork)
{
_context = context;
_unitOfWork = unitOfWork;
}
}
public class AccountService : IAccountService
{
private readonly IUnitOfWorkAsync _uow;
private readonly IRepositoryAsync<Account> _repository;
public AccountService(IUnitOfWorkAsync uow, IRepositoryAsync<Account> repository)
{
_uow = uow;
_repository = repository;
}
}
我試圖像這樣在我的容器中注冊它們(順便說一句,我正在使用WCF)。
var builder = new ContainerBuilder();
builder.RegisterType<MyDbContext>().As<IDataContextAsync>();
builder.RegisterType<UnitOfWork>().As<IUnitOfWorkAsync>();
builder.RegisterGeneric(typeof(Repository<>)).As(typeof(IRepositoryAsync<>));
builder.RegisterAssemblyTypes(typeof(AccountService).Assembly)
.Where(t => t.Name.EndsWith("Service"))
.As(t => t.GetInterfaces().FirstOrDefault(
i => i.Name == "I" + t.Name));
Container = builder.Build();
似乎注入到AccountService的unitOfWork容器生成的實例與容器實例化存儲庫時創建的unitOfWork實例不同。 如何確保使用相同的實例實例化存儲庫? 例如,這是通常在沒有容器的情況下實例化對象的方式。
var context = new MyDbContext();
_uow = new UnitOfWork(context);
_repository = new Repository<Account>(context, _uow);
AccountService service = new AccountService(_uow, _repository);
如您所見,創建存儲庫的_uow
和_uow
參數是同一實例。 當Autofac實例化對象時情況並非如此,我似乎無法弄清楚如何將它們“綁在一起”。
默認情況下, Autofac范圍是每個依賴項的。 這意味着Autofac每次需要解決依賴項時,都會返回一個新實例。
如果要在整個生命周期或請求中擁有一個公共實例,則必須使用適當的范圍來注冊類型。
var builder = new ContainerBuilder();
builder.RegisterType<MyDbContext>()
.As<IDataContextAsync>()
.InstancePerLifetimeScope();
builder.RegisterType<UnitOfWork>()
.As<IUnitOfWorkAsync>()
.InstancePerLifetimeScope();
builder.RegisterGeneric(typeof(Repository<>))
.As(typeof(IRepositoryAsync<>))
.InstancePerLifetimeScope();
builder.RegisterAssemblyTypes(typeof(AccountService).Assembly)
.Where(t => t.Name.EndsWith("Service"))
.As(t => t.GetInterfaces().FirstOrDefault(i => i.Name == "I" + t.Name))
.InstancePerLifetimeScope();
Container = builder.Build();
有關更多信息,請參見Autofac文檔中的“ 實例范圍” 。
順便說一句, Autofac與WCF的集成似乎不支持每個請求的生命周期范圍
由於WCF內部的原因,WCF中沒有針對每個請求生命周期依賴性的顯式支持。
此限制與WCF具有自己的實例范圍的事實有關。 建議使用InstanceContextMode.PerCall
來確保WCF為每個WCF調用詢問服務的新實例。 您可以使用ServiceBehavior
屬性
[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall)]
public class MyService : IMyService
{ }
我閱讀了AutofacInstanceContext.cs的源代碼,似乎為每個WCF調用都創建了一個新的LifetimeScope 。 因此,您可以將依賴項注冊為InstancePerLifetimeScope
,它應該可以工作。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.