Autofac:使用Web API 2进行设置,我缺少什么

时间:2015-11-09 08:01:17

标签: c# .net asp.net-mvc asp.net-web-api2 autofac

我在一个独立的C#解决方案中测试Autofac,我想将一个测试管理器注入到家庭控制器中,它的设置如下:

一个非常简单的界面

public interface ITestManager
{
    IEnumerable<string> Get();
}

实施
public class TestManager : ITestManager
{
    public IEnumerable<string> Get()
    {
        return new List<string>
        {
            "Lorem ipsum dolor sit amet, consectetur adipiscing elit, ",
            "sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. ",
            "Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut ",
            "aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in ",
            "voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint ",
            "occaecat cupidatat non proident, sunt in culpa qui officia ",
            "deserunt mollit anim id est laborum."
        };
    }
}

这将由TestController接收

public class TestController : Controller
{
    private ITestManager TestManager { get; set; }

    public TestController(ITestManager testManager)
    {
        TestManager = testManager;
    }
}

依赖关系设置如下

public static class Autofac
{
    public static void Register(HttpConfiguration config)
    {
        // Base set-up
        var builder = new ContainerBuilder();

        // Register your Web API controllers.
        builder.RegisterApiControllers(Assembly.GetExecutingAssembly());

        // OPTIONAL: Register the Autofac filter provider.
        builder.RegisterWebApiFilterProvider(config);

        // Register dependencies

        SetUpRegistration(builder);

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

        // Set the dependency resolver to be Autofac.
        config.DependencyResolver = new AutofacWebApiDependencyResolver(container);
    }

    private static void SetUpRegistration(ContainerBuilder builder)
    {
        builder.RegisterType<TestManager>()
            .As<ITestManager>()
            .InstancePerLifetimeScope();
    }
}

从global.asax

中链接
protected void Application_Start()
{
    AreaRegistration.RegisterAllAreas();
    GlobalConfiguration.Configure(WebApiConfig.Register);
    FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
    RouteConfig.RegisterRoutes(RouteTable.Routes);
    BundleConfig.RegisterBundles(BundleTable.Bundles);

    IoC.Autofac.Register(GlobalConfiguration.Configuration);
}

运行此会导致此错误:

  应用程序中的服务器错误。

     

没有为此对象定义无参数构造函数。

     

描述:执行期间发生了未处理的异常   当前的网络请求。请查看堆栈跟踪了解更多信息   有关错误的信息以及它在代码中的起源。

     

异常详细信息:System.MissingMethodException:无参数   为此对象定义的构造函数。

我错过了什么?

完整堆栈跟踪:

堆栈跟踪

[MissingMethodException: No parameterless constructor defined for this object.]
   System.RuntimeTypeHandle.CreateInstance(RuntimeType type, Boolean publicOnly, Boolean noCheck, Boolean& canBeCached, RuntimeMethodHandleInternal& ctor, Boolean& bNeedSecurityCheck) +0
   System.RuntimeType.CreateInstanceSlow(Boolean publicOnly, Boolean skipCheckThis, Boolean fillCache, StackCrawlMark& stackMark) +119
   System.RuntimeType.CreateInstanceDefaultCtor(Boolean publicOnly, Boolean skipCheckThis, Boolean fillCache, StackCrawlMark& stackMark) +232
   System.Activator.CreateInstance(Type type, Boolean nonPublic) +83
   System.Activator.CreateInstance(Type type) +11
   System.Web.Mvc.DefaultControllerActivator.Create(RequestContext requestContext, Type controllerType) +55

[InvalidOperationException: An error occurred when trying to create a controller of type 'AutofacWebApi.Controllers.HomeController'. Make sure that the controller has a parameterless public constructor.]
   System.Web.Mvc.DefaultControllerActivator.Create(RequestContext requestContext, Type controllerType) +178
   System.Web.Mvc.DefaultControllerFactory.GetControllerInstance(RequestContext requestContext, Type controllerType) +76
   System.Web.Mvc.DefaultControllerFactory.CreateController(RequestContext requestContext, String controllerName) +88
   System.Web.Mvc.MvcHandler.ProcessRequestInit(HttpContextBase httpContext, IController& controller, IControllerFactory& factory) +191
   System.Web.Mvc.MvcHandler.BeginProcessRequest(HttpContextBase httpContext, AsyncCallback callback, Object state) +50
   System.Web.Mvc.MvcHandler.BeginProcessRequest(HttpContext httpContext, AsyncCallback callback, Object state) +48
   System.Web.Mvc.MvcHandler.System.Web.IHttpAsyncHandler.BeginProcessRequest(HttpContext context, AsyncCallback cb, Object extraData) +16
   System.Web.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() +103
   System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) +155

1 个答案:

答案 0 :(得分:3)

这很简单,我从HomeController复制了控制器类信息,类型为Controller,而不是ApiController

所以正确的实现是:

public class TestController : ApiController
{
    private ITestManager TestManager { get; set; }

    public TestController(ITestManager testManager)
    {
        TestManager = testManager;
    }

    // GET: api/Test
    public IEnumerable<string> Get()
    {
        return this.TestManager.Get();
    }
}

我使用builder.RegisterApiControllers(Assembly.GetExecutingAssembly())来注册控制器,但这仅适用于API控制器,而且,由于我的TestController类型为Controller(这是核心MVC控制器类型),因此它不是'连接正确。

如果你想使用(普通的)MVC,你应该使用它:

builder.RegisterControllers(Assembly.GetExecutingAssembly())

感谢wal指出我正确的方向。