我在我的WebApi项目中使用Autofac,直到现在一切都运行良好。例如,我注册:
builder.Register(x => new LogService())
.As<ILogService>().Exported(x => x.As<ILogService>()).SingleInstance();
builder.RegisterType(typeof(UnitOfWork)).As(typeof(IUnitOfWork))
.InstancePerRequest();
以上的作品就像魅力一样。请注意Exported
。
但是,现在我添加了MEF,以便我可以实现插件架构。我还添加了Autofac.Mef,以便我可以将在Autofac中注册的类型导出回MEF。
所以对于上面的Autofac配置,我还补充说:
builder.RegisterType<ImportFactory>()
.As<IImportFactory>()
.Exported(x => x.As<IImportFactory>())
.InstancePerLifetimeScope();
这个工厂类只根据导入类型(例如客户,产品等)为我提供了所需的各种服务。这些服务都注册为InstancePerRequest
。工厂类看起来像这样:
public class ImportFactory : BaseService, IImportFactory
{
public ImportFactory(ILogService logService, IUnitOfWork unitOfWork)
: base(logService, unitOfWork) { }
}
插件看起来像这样:
[Export(typeof(IImportPlugin))]
public class ImportCustomers : ImportPlugin, IImportPlugin
{
private ICustomerService customerService;
[ImportingConstructor]
public ImportCustomers(ILogService logService, IImportFactory importFactory)
: base()
{
this.logService = logService;
this.importFactory = importFactory;
}
}
每个插件都有一个允许它在Autofac中注册的模块:
[Export(typeof(IModule))]
public class AutofacModule : Module
{
protected override void Load(ContainerBuilder builder)
{
builder.RegisterType<ImportCustomers>()
.Exported(x => x.As<IImportPlugin>())
.InstancePerLifetimeScope();
}
}
此外,在我的控制器中,我在一个单独的线程中启动我的导入作业,如下所示:
public class ImportController : BaseController
{
private readonly IComponentContext componentContext;
public ImportController(IComponentContext componentContext, ILogService logService)
: base(logService)
{
this.componentContext = componentContext;
}
public IHttpActionResult Start()
{
var config = componentContext.Resolve<IPluginConfig>();
var plugins = config.ImportPlugins;
HostingEnvironment.QueueBackgroundWorkItem(ct =>
{
plugins.First().Import(); //Just to test
});
return Ok();
}
}
然而,当Autofac注入依赖项时,我现在混合了范围,因为我收到以下错误
无法解析类型&#39; App.Common.Logging.LogService&#39;因为它所属的生命范围无法找到。此注册公开了以下服务: - App.Common.Logging.ILogService
详情---&gt;没有标记匹配的范围&#39; AutofacWebRequest&#39;从请求实例的范围可见。
如果在执行Web应用程序期间看到此情况,则通常表示SingleInstance()组件(或类似方案)正在请求按HTTP请求注册的组件。在Web集成下,始终从依赖项解析程序或请求生存期范围请求依赖项,而不是从容器本身请求。 (详见内部异常。)
如果所有类型都注册为InstancePerLifetimeScope
,那么一切正常,即Autofac按预期注入依赖项。但问题在于类型具有不同的范围。这是因为,例如,ImportFactory
为InstancePerLifetimeScope
,并且它依赖于IUnitOfWork
InstancePerRequest
。
正确的注册是什么,以便可以在不使用辅助容器和服务位置的情况下正确注入依赖项?本地范围可以做到吗?