将Autofac与自托管WebApi一起使用 - 控制器未注册

时间:2013-11-06 13:08:43

标签: c# dependency-injection asp.net-web-api autofac

我是自托管WebApi应用程序以进行一些集成测试。

我设置了我的服务器:

var httpConfig = new HttpSelfHostConfiguration(BaseAddress);

new ApiServiceConfiguration(httpConfig)
    .Configure();

var server = new HttpSelfHostServer(httpConfig);
server.OpenAsync().Wait();
Server = server; //this is just a property on the containing class

ApiServiceConfiguration是一个允许我抽象WebApi配置的类(所以我可以在Global.asax中使用它来支持api的IIS托管版本)

这是一个摘录:

public class ApiServiceConfiguration 
   {
       private readonly HttpConfiguration _httpConfiguration;

       public ApiServiceConfiguration(HttpConfiguration httpConfiguration)
       {
           _httpConfiguration = httpConfiguration;
       }

       public void Configure()
       {
           //setup routes
           RouteConfig.RegisterRoutes(_httpConfiguration.Routes);

           //setup autofac
           AutofacConfig.Setup(_httpConfiguration);

我的AutofacConfig.Setup静态方法只是:

public static void Setup(HttpConfiguration config)
{
    var builder = new ContainerBuilder();

    // Register the Web API controllers.
    builder.RegisterApiControllers(Assembly.GetAssembly(typeof(MyController)));

    // Register dependencies.

    // Build the container.
    var container = builder.Build();

    // Configure Web API with the dependency resolver.
    //notice config is passed in as a param in containing method
    config.DependencyResolver = new AutofacWebApiDependencyResolver(container);
}

然而,当我从我的单元测试中调用我的api时:

using (var client = new HttpClient(Server))
{
    var result = client.PostAsync(BaseAddress + "api/content/whatever"

    var message = result.Content.ReadAsStringAsync().Result;
}

消息的价值是:

  

发生了错误。“,”ExceptionMessage“:”尝试创建'ContentController'类型的控制器时发生错误。确保控制器具有无参数的公共构造函数。“,”ExceptionType“:”System.InvalidOperationException“,”StackTrace“:”at System.Web.Http.Dispatcher.DefaultHttpControllerActivator.Create(HttpRequestMessage request,HttpControllerDescriptor controllerDescriptor,Type controllerType)在System.Web.Http.Dispatcher.HttpControllerDispatcher.d__0.MoveNext处的System.Web.Http.Dispatcher.HttpControllerDispatcher.SendAsyncCore(HttpRequestMessage请求,CancellationToken cancellationToken)的System.Web.Http.Controllers.HttpControllerDescriptor.CreateController(HttpRequestMessage请求)处。 )“,”InnerException“:{”消息“:”发生错误。“,”ExceptionMessage“:”类型'My.Namespace.ContentController'没有默认构造函数“,”ExceptionType“:”System.ArgumentException“ ,“StackTrace”:“在System.Web.Http.Dinpatcher.DefaultHttpContr的System.Web.Http.Inteal.TypeActivator.Create [TBase](Type instanceType)中的System.Linq.Expressions.Expression.New(Type type) ollerActivator.GetInstanceOrActivator(HttpRequestMessage请求,类型controllerType,Func`1& System.Web.Http.Dispatcher.DefaultHttpControllerActivator.Create(HttpRequestMessage请求,HttpControllerDescriptor controllerDescriptor,类型controllerType)

这表明Autofac控制器注册无效。

如果我在设置中的下一行贴了一个断点:

var server = new HttpSelfHostServer(httpConfig);

并使用即时窗口检查httpConfig.DependencyResolver它确实与Autofac相关

2 个答案:

答案 0 :(得分:1)

您需要将ContainerBuilder和DependencyResolver移出静态类。您的实现使用后期绑定,autofac依赖性解析程序不替换默认解析程序。

您可以在错误消息中看到:"确保控制器具有无参数的公共构造函数。"

默认解析器无法在没有无参数构造函数的情况下处理控制器,这是构造函数注入所必需的。

答案 1 :(得分:0)

我遇到了同样的问题。就我而言,问题在于使用Assembly.GetCallingAssembly()。我想获得调用程序集并将其传递给Autofac以注册控制器。但在发布模式下,它无效。

阅读以下文章后:

http://www.ticklishtechs.net/2010/03/04/be-careful-when-using-getcallingassembly-and-always-use-the-release-build-for-testing/

我刚刚删除了GetCallingAssembly调用,并替换为显式传递程序集,如typeof(Startup).Assembly