Webapi环境中的Sharprepository Autofac InstancePerApiRequest无法正常工作

时间:2013-10-03 15:43:06

标签: autofac sharp-repository

是否有人使用InstancePerApiRequest为DbContext提供了使用autofac进行sharprepository集成的工作示例?

我正在注册我的dbcontext:

builder.RegisterType<AuditTestEntities>().As<DbContext>().InstancePerApiRequest();

如果我删除InstancePerApiRequest,则sharprepository可以获取dbcontext。但是使用InstancePerApiRequest,我得到下面粘贴的错误消息。基本上,我怀疑,错误的关键在于sharprepository进行调用的方式:

  

从请求实例的作用域中看不到具有匹配'AutofacWebRequest'的标记的作用域。这通常表示SingleInstance()组件(或类似场景)正在请求注册为每HTTP请求的组件。在Web集成下,始终从DependencyResolver.Current或ILifetimeScopeProvider.RequestLifetime请求依赖项,从不从容器本身请求

完整的错误堆栈:

  

iisexpress.exe错误:0:Operation = DefaultHttpControllerActivator.Create,Exception = System.InvalidOperationException:尝试创建“AccountController”类型的控制器时发生错误。确保控制器具有无参数的公共构造函数。 ---&GT; Autofac.Core.DependencyResolutionException:在类型'AccountRepository'上调用构造函数'Void .ctor()'时抛出异常。 ---&GT;无法使用'AutofacDependencyResolver'解析类型'System.Data.Entity.DbContext'。确保已为此类型配置了Ioc容器。查看InnerException以获取更多详细信息。 (详见内部异常。)---&gt; SharpRepository.Repository.Ioc.RepositoryDe​​pendencyResolverException:无法使用'AutofacDependencyResolver'解析类型'System.Data.Entity.DbContext'。确保已为此类型配置了Ioc容器。查看InnerException以获取更多详细信息。 ---&GT; Autofac.Core.DependencyResolutionException:从请求实例的作用域中看不到具有匹配'AutofacWebRequest'的标记的作用域。这通常表示SingleInstance()组件(或类似场景)正在请求注册为每HTTP请求的组件。在Web集成下,始终从DependencyResolver.Current或ILifetimeScopeProvider.RequestLifetime请求依赖项,从不从容器本身请求

2 个答案:

答案 0 :(得分:1)

好的,发现了这个问题。在使用MVC或Web API集成并尝试使用范围InstancePerApiRequest或InstancePerHttpRequest时,使用SharpRepository AutofacDependencyResolver时出现问题。 Autofac希望通过System.Web.DependencyResolver.Current来解析这些项​​目,而不是像AutofacDependencyResolver当前那样直接从Autofac IContainer解析。

以下是您现在可以解决问题的方法,直到我们为AutofacDependencyResolver进行重载来解决问题。

您需要在项目中创建自己的依赖项解析器,如下所示:

public class CustomAutofacDependencyResolver : BaseRepositoryDependencyResolver
{
    private readonly IDependencyResolver _resolver;

    public CustomAutofacDependencyResolver(IDependencyResolver resolver)
    {
        _resolver = resolver;
    }

    protected override T ResolveInstance<T>()
    {
        return _resolver.GetService<T>();
    }

    protected override object ResolveInstance(Type type)
    {
        return _resolver.GetService(type);
    }
}

然后将其注册到SharpRepository,以便它将使用它来解析DbContext,然后它将按预期工作。

RepositoryDependencyResolver.SetDependencyResolver(new CustomAutofacDependencyResolver(DependencyResolver.Current));

**更新** 我正在使用MVC进行测试并能够复制错误并修复它,但这不适用于Web API。我习惯使用StructureMap,使用GlobalConfiguration.Configuration.DependencyResolver可以正常工作。

似乎问题是Autofac需要一个IDependencyScope,你可以从HttpRequestMessage访问,但我没有看到在ApiController之外的方法。这描述了问题和原因:https://groups.google.com/forum/#!msg/autofac/b3HCmNE_S2M/oMmwFE5uD80J

不幸的是,现在我处理这个问题的最佳方式有点亏。但我会继续考虑它。

答案 1 :(得分:0)

所以,我能够通过将生命周期范围更改为InstancePerLifetimeScope来让我的工作变得更好。我不知道这是否有任何不可预见的后果。到目前为止,一切似乎都对我有用。