依赖注入无法与Owin自托管Web Api 2和Autofac一起使用

cee*_*enk 25 c# autofac owin asp.net-web-api2

我正在寻找Web Api 2,Owin和Autofac,并需要一些指导.

概述
我有一个Owin自托管的Web Api,它使用Autofac进行IoC和依赖注入.该项目是一个控制台应用程序,就像一个服务,这意味着它可以停止和启动.我有一个带有两个构造函数的身份验证控制器:一个参数少,另一个注入存储库.

问题
当我运行服务并调用api时,我的无参数构造函数被调用,我的存储库永远不会被注入(_repository = null).

研究
我做了一些研究,并在Github上发现了一些有用的项目,我将其复制到了发球台,但我错过了很大一部分难题.很有帮助,但没有解决我的问题.我在Stack Overflow上阅读了这个问题,Dane Sparza有一个很好的演示项目,但我找不到一个明确的解决方案.问题不是自托管而是依赖注入.

我的代码(细化了解释)

public class Startup
{
    public void Configuration(IAppBuilder app)
    {
        HttpConfiguration config = new HttpConfiguration();

        config.Routes.MapHttpRoute(
            name: "DefaultApi",
            routeTemplate: "api/{controller}/{id}",
            defaults: new { id = RouteParameter.Optional }
        );

        var json = config.Formatters.JsonFormatter;
        json.SerializerSettings.PreserveReferencesHandling = Newtonsoft.Json.PreserveReferencesHandling.Objects;
        config.Formatters.Remove(config.Formatters.XmlFormatter);

        var connectioninfo = ConnectionInfo.FromAppConfig("mongodb");

        var builder = new ContainerBuilder();                                    // Create the container builder.
        builder.RegisterApiControllers(Assembly.GetExecutingAssembly());         // Register the Web API controllers.
        builder.Register(c => new Logger()).As<ILogger>().InstancePerRequest();  // Register a logger service to be used by the controller and middleware.
        builder.RegisterType<AuthenticationRepository>().As<IAuthenticationRepository>().WithParameter(new NamedParameter("connectionInfo", connectioninfo)).InstancePerRequest();

        var container = builder.Build();

        var resolver = new AutofacWebApiDependencyResolver(container);           // Create an assign a dependency resolver for Web API to use.
        GlobalConfiguration.Configuration.DependencyResolver = resolver;         // Configure Web API with the dependency resolver

        app.UseCors(CorsOptions.AllowAll);  
        app.UseWebApi(config);
        app.UseAutofacWebApi(config);  // Make sure the Autofac lifetime scope is passed to Web API.
    }
Run Code Online (Sandbox Code Playgroud)

Program.cs中

 static void Main(string[] args)
    {           
        var service = new ApiService(typeof(Program), args);

        var baseAddress = "http://localhost:9000/";
        IDisposable _server = null;

        service.Run(
           delegate()
           {
               _server = WebApp.Start<Startup>(url: baseAddress);
           },
           delegate()
           {
               if (_server != null)
               {
                   _server.Dispose();
               }
           }
       );
    }
Run Code Online (Sandbox Code Playgroud)

ApiController

public class AuthenticationController : ApiController
{
    private IAuthenticationRepository _repository;

    public AuthenticationController() { }

    public AuthenticationController(IAuthenticationRepository repository)
    {
        _repository = repository;
    }

    [AllowAnonymous]
    public IHttpActionResult Authenticate(string name, string password)
    {
        if (_repository == null)
            return BadRequest("User repository is null.");

        var valid = _repository.AuthenticateUser(name, password);
        return Ok(valid);
    }
}
Run Code Online (Sandbox Code Playgroud)

Mar*_* N. 38

你应该使用HttpConfiguration你在任何地方引导OWIN的那个.所以这:

GlobalConfiguration.Configuration.DependencyResolver = resolver;
Run Code Online (Sandbox Code Playgroud)

应该成为:

config.DependencyResolver = resolver;
Run Code Online (Sandbox Code Playgroud)

除此之外,一切看起来都不错.Api控制器已注册,但您没有给它们一个范围.不确定Autofac作用域中是否默认为每个请求控制器,或者它是否具有每个请求作用域的概念(我知道LightInject有它).

环顾四周,我认为您遵循Autofac的Google Code repo上的示例,它确实使用了GlobalConfiguration.相反,如果你看一下GitHub的例子,它会有所不同.尝试根据此进行更改.包括这个:

// This should be the first middleware added to the IAppBuilder.
app.UseAutofacMiddleware(container);
Run Code Online (Sandbox Code Playgroud)

2016年更新

我上面说的内容仍然适用,但Autofac的文档中提供了额外的内容(感谢Brad):

OWIN集成中的常见错误是使用GlobalConfiguration.Configuration.在OWIN中,您可以从头开始创建配置.使用OWIN集成时,不应在任何地方引用GlobalConfiguration.Configuration.

  • 对于任何新人来说,这是Autofac关于Owin/WebApi的文档:http://autofac.readthedocs.org/en/latest/integration/webapi.html#owin-integration (4认同)
  • 这个答案也适用于Unity. (3认同)